blob: 1eb34eedefa3318c82ad3f0e08015af9b0e282bd [file] [log] [blame]
= TomEE and Arquillian
:jbake-date: 2016-03-16
:jbake-type: page
:jbake-status: published
:jbake-tomeepdf:
TomEE has several arquillian adapter flavors:
- openejb-embedded: a plain embedded OpenEJB supporting most of EE features
- tomee-embedded: a full TomEE running in the same JVM
- tomee-remote: a standard TomEE running in its own process as in production
- tomee-webapp (not recommanded): an adapter starting from a Tomcat and installing tomee-webapp
=== Embedded or Remote?
Big advantage of embedded adapters is to be able to debug as usual. However it has few drawbacks which can make you
rething this choice:
- JVM resources are available where it will likely not be the case in war mode (src/main/resources typically)
- You can mix server and client side features when writing a test
- Classloading is a bit different by design and less isolated (test dependencies) so you can get runtime surprises when really deploying
To summarize: the choice is the trade off you choose between easiness and reality of the simulation.
TIP: in TomEE build we build the same tests against all tomee adapters in the same build/module, this means you can use embedded adapter in dev
and activate remote tomee too (not only cause then if there is a failure you don't know if you missed it locally or if it is due
to the switch of adapter) on your continuous integration platform.
NOTE: all configurations have defaults
=== OpenEJB Embedded
==== Coordinates
[source,xml]
----
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>arquillian-openejb-embedded</artifactId>
<version>${tomee7.version}
</dependency>
----
==== arquillian.xml
|===
|Name|Description
|properties|container properties, as in conf/system.properties (not in xml format)
|preloadClasses|some class to load (ie enforce static block initialization)
|startDefaultScopes|should CDI default scopes be started (includes @RequestScoped)
|singleDeploymentByArchiveName |names of archives (or true for all) to dploy a single time
|===
Sample:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<arquillian
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="openejb" default="true">
<configuration>
<property name="properties">
# used to not have a single DataSource and be able to test the resource resolution
db1 = new://Resource?type=DataSource
db1.JdbcUrl = jdbc:hsqldb:mem:db1
# will preload both classes, simple comma separated qualified names work too
openejb.arquillian.predeploy-archives = org.company.openejb.arquillian.openejb.archive.[SimpleArchive|SimpleArchive2]
</property>
</configuration>
</container>
</arquillian>
----
=== TomEE Embedded
==== Coordinates
[source,xml]
----
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>arquillian-tomee-embedded</artifactId>
<version>${tomee7.version}
</dependency>
----
==== Configuration
|===
|Name|Description
| exportConfAsSystemProperty|export system properties with adapter prefix(es) (ex: httpPort will be set as tomee.httpPort)
| httpsPort | the HTTPS port
| httpPort | the HTTP port
| stopPort | the shutdown port
| dir | where to create the TomEE work dir (a fake file layout is created for Tomcat needs)
| appWorkingDir | where to dump applications (`@Deployment`)
| host | which host to use
| stopHost | which port to use to shutdown TomEE (port on Server configuration)
| stopCommand | which command to use to shutdown TomEE
| serverXml | where is the provided server.xml
| portRange | when port are set to -1 TomEE adapter will generate an available port, if specified the range will be used
| preloadClasses | which classes to initialize during container startup
| quickSession | should the session use a Random instead of SecureRandom (useful when the machine doesn't have a lot of entropy)
| unsafeEjbd | should EJB allow all classes
| unpackWars | unpackWARs value in server.xml
| properties | container properties
| webContextToUseWithEars |sometimes you can need this to adjust which context the adapter uses to find the ArquillianServletRunner
| keepServerXmlAsThis |don't replace ports etc in server.xml and use it like it has been provided when serverXml is set
| singleDumpByArchiveName | dump only once `@Deployment` archives using the name as key
| singleDeploymentByArchiveName |deploy only once `@Deployment` archives using the name as key
|ssl| should https be activated
|withEjbRemote| should EJBd remote be activated
|keystoreFile | if ssl is set to true the keystore location
|keystorePass | if ssl is set to true the keystore password
|keystoreType | if ssl is set to true the keystore type
|clientAuth |should SSL connector use clientAuth
|keyAlias | if ssl is set to true the key to use
|sslProtocol | if ssl is set to true the protocol to use
|users |a map of users (properties syntax)
|roles |user roles (properties syntax)
|webResourcesCached |should resources be cached or not (`DefaultServlet` caching)
|===
Sample:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<arquillian
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="tomee" default="true">
<configuration>
<property name="serverXml">conf/server.xml</property>
<!-- port = -1 means random -->
<property name="httpPort">-1</property>
<property name="stopPort">-1</property>
<!-- ssl -->
<property name="httpsPort">-1</property>
<property name="ssl">false</property>
<property name="keystoreFile">keystore-path</property>
<property name="keystorePass">changeit</property>
<property name="keystoreType">JKS</property>
<property name="clientAuth">false</property>
<property name="keyAlias">alias</property>
<property name="sslProtocol">protocol</property>
<!-- where to create TomEE files -->
<property name="dir">target/tomee-embedded</property>
<!-- where to dump on disk applications to deploy -->
<property name="appWorkingDir">target/working-dir</property>
<!-- optional - limit the port allowed when random -->
<property name="portRange">20001-30000</property>
<!-- container config -->
<property name="properties">
# same as embedded case
</property>
<!-- Deployer config -->
<property name="deployerProperties">
# openejb.deployer.binaries.use=true
# openejb.deployer.forced.appId=[name]
# openejb.deployer.save-deployments=false
</property>
</configuration>
</container>
</arquillian>
----
=== TomEE Remote
IMPORTANT: if a server is already started on host:port then it will be used instead of starting the configured TomEE type.
To use a custom instance with arquillian ensure to have ejbd and tomee webapp activated. A way is to have in `conf/system.properties` these entries:
[source]
----
tomee.remote.support=true
openejb.system.apps=true
# you can customize it depending the security level you need on the instance
tomee.serialization.class.whitelist =
tomee.serialization.class.blacklist = org.codehaus.groovy.runtime.,org.apache.commons.collections.functors.,org.apache.xalan,java.lang.Process
----
For really remote instances (= not on localhost) you need the `deployerProperties` of previous snippet too:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<arquillian
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="tomee" default="true">
<configuration>
<!-- ... -->
<property name="deployerProperties">
openejb.deployer.binaries.use=true
openejb.deployer.save-deployments=false
</property>
</configuration>
</container>
</arquillian>
----
==== Coordinates
[source,xml]
----
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>arquillian-tomee-remote</artifactId>
<version>${tomee7.version}
</dependency>
----
==== Configuration
|===
|Name|Description
| exportConfAsSystemProperty|export system properties with adapter prefix(es) (ex: httpPort will be set as tomee.httpPort)
| httpsPort | the HTTPS port
| httpPort | the HTTP port
| stopPort | the shutdown port
| dir | where to create the TomEE work dir (a fake file layout is created for Tomcat needs)
| appWorkingDir | where to dump applications (`@Deployment`)
| host | which host to use
| stopHost | which port to use to shutdown TomEE (port on Server configuration)
| stopCommand | which command to use to shutdown TomEE
| serverXml | where is the provided server.xml
| portRange | when port are set to -1 TomEE adapter will generate an available port, if specified the range will be used
| preloadClasses | which classes to initialize during container startup
| quickSession | should the session use a Random instead of SecureRandom (useful when the machine doesn't have a lot of entropy)
| unsafeEjbd | should EJB allow all classes
| unpackWars | unpackWARs value in server.xml
| properties | container properties
| webContextToUseWithEars |sometimes you can need this to adjust which context the adapter uses to find the ArquillianServletRunner
| keepServerXmlAsThis |don't replace ports etc in server.xml and use it like it has been provided when serverXml is set
| singleDumpByArchiveName | dump only once `@Deployment` archives using the name as key
| singleDeploymentByArchiveName |deploy only once `@Deployment` archives using the name as key
|groupId|the maven groupId of the TomEE (or not) artifact
|artifactId|the maven artifactId of the TomEE (or not) artifact
|version |the maven version of the TomEE (or not) artifact
|classifier |the maven classifier of the TomEE (or not) artifact
|type |the maven type of the TomEE (or not) artifact (should be zip)
|removeUnusedWebapps |should default webapps (ROOT, manager, ...) be removed
|ajpPort |the ajp port if used
|conf |a folder to synchronize with TomEE conf folder
|bin |a folder to synchronize with TomEE bin folder
|lib |a folder to synchronize with TomEE lib folder
|endorsed |a folder to synchronize with TomEE endorsed folder
|javaagent |a list (flat format) of javaagent to add when launching tomee, can use maven coordinates if prefixed with `mvn:`
|additionalLibs |a list (flat format) of library to add to TomEE libraries, can use paths of maven coordinates when prefixed with `mvn:`
|cleanOnStartUp |should TomEE folder be deleted on startup if exists
|debug |should the container run in debug mode (`-Dopenejb.server.debug=true` activates it without touching the configuration)
|debugPort |if activated which port to use to debug
|catalina_opts |equivalent to `CATALINA_OPTS` environment variable
|simple_log |should logs be inline
|deployerProperties |deployer properties, useful when not deploying on an instance managed by the build (remote instance typically)
|===
Sample:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<arquillian
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="tomee" default="true">
<configuration>
<property name="serverXml">conf/server.xml</property>
<!-- tomee zip to use -->
<property name="groupId">org.apache.tomee</property>
<property name="artifactId">apache-tomee</property>
<property name="version">LATEST</property>
<property name="type">zip</property>
<!-- tomee provided files, ignored by default -->
<property name="bin">src/test/tomee/bin</property>
<property name="conf">src/test/tomee/conf</property>
<property name="lib">src/test/tomee/lib</property>
<!--
remote debugging,
-Dopenejb.server.debug can activate it too
-->
<property name="debug">false</property>
<property name="debugPort">5005</property>
<!-- nice one line logging -->
<property name="simpleLog">true</property>
<!-- jvm config -->
<property name="catalina_opts">-XX:-UseParallelGC</property>
<!-- remove if exist -->
<property name="cleanOnStartUp">true</property>
<!-- remove default webapps -->
<property name="removeunusedWebapps">true</property>
<!-- port = -1 means random -->
<property name="httpPort">-1</property>
<property name="stopPort">-1</property>
<!-- where to create TomEE -->
<property name="dir">target/apache-tomee</property>
<!-- where to dump on disk applications to deploy -->
<property name="appWorkingDir">target/working-dir</property>
<!-- optional - limit the port allowed when random -->
<property name="portRange">20001-30000</property>
<!-- container config -->
<property name="properties">
# same as embedded case
</property>
<!-- we monitor the test with sirona -->
<property name="javaagent">
mvn:org.apache.sirona:sirona-javaagent:0.2-incubating:jar:shaded
</property>
<!-- Deployer config -->
<property name="deployerProperties">
# openejb.deployer.binaries.use=true
# openejb.deployer.forced.appId=[name]
# openejb.deployer.save-deployments=false
</property>
</configuration>
</container>
</arquillian>
----
=== Multiple instances
With arquillian you can create cluster or isolated instances. Here is a sample `arquillian.xml`:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<group qualifier="tomee-cluster">
<container qualifier="tomee-1">
<configuration>
<property name="httpPort">-1</property>
<property name="stopPort">-1</property>
<property name="ajpPort">-1</property>
<property name="dir">target/tomee1</property>
<property name="appWorkingDir">target/wd1</property>
</configuration>
</container>
<container qualifier="tomee-2">
<configuration>
<property name="httpPort">-1</property>
<property name="stopPort">-1</property>
<property name="ajpPort">-1</property>
<property name="dir">target/tomee2</property>
<property name="appWorkingDir">target/wd2</property>
</configuration>
</container>
</group>
</arquillian>
----
Then in your test just specify the container you are testing against:
[source,java]
----
@RunWith(Arquillian.class)
public class MultipleTomEETest {
@Deployment(name = "war1", testable = false)
@TargetsContainer("tomee-1")
public static WebArchive war1() {
return /* ... */;
}
@Deployment(name = "war2", testable = false)
@TargetsContainer("tomee-2")
public static WebArchive war2() {
return /* ... */;
}
@Test
@OperateOnDeployment("war1")
public void testRunningInDep1(
@ArquillianResource URL url) {
// test on tomee 1, url is contextual
}
@Test
@OperateOnDeployment("war2")
public void testRunningInDep1(
@ArquillianResource URL url) {
// test on tomee 1, url is contextual
}
}
----