(This is a constantly updated article, be sure to check back for updates!)
Configuring OpenEJB (or TomEE) can be a bit of a pain as its not always obvious where to place the specific settings you want. I will describe in as much detail in how you can configure it in the various forms, whether XML, properties or the newly introduced JSON config!
The intention is to have this article as your one stop shop in finding all the possible ways to configure your OpenEJB instance. With this info, you can truly master your server backend.
In a typical config of OpenEJB, all config files are stored in the ${OPENEJB_HOME}/conf directory, period (no need to go looking elsewhere). You have several config files available to you:
- conf/openeb.xml | conf/openejb.json: Define your container settings, resources etc.
- conf/system.properties: Define general settings OpenEJB settings such as the jax-rs providers, whether to deploy the standard OpenEJB apps etc.
- conf/logging.properties: Customize how logging is done by the container.
- conf/login.config: Define your LoginModule classes here to be used by JAAS to login users.
If you don't provide any of these in the ${OPENEJB_HOME}/conf
directory, then OpenEJB will generate the defaults for you. So if you don't want the defaults, you should at least provide these with nothing inside (for the openejb.xml have at least the tag inside).
The container will also generate some properties files in ${OPENEJB_HOME}/conf/conf.d/
Please note that all JSON snippets for the openejb.json must be instered into a root { }.
Likewise, all the xml snippets for openejb.xml must be inserted in a root .
So the deployments config pretty much states where your ejb-jars are going to lie within the OpenEJB container directory. This is typically in ${OPENEJB_HOME}/apps
.
(a) JSON - conf/openejb.json:
"deployments": {
"apps": {
"dir": "apps"
}
}
(b) XML - conf/openejb.xml:
<Deployments dir="apps/"/>
The resources of your openejb app are things like your jdbc data sources (for e.g to be used by your JPA provider). You can specify the id of the data source and a set of properties. Properties include things like the jdbc driver and login credentials. Specifying the driver is the important part to set, as it defines what database you want to use, whether it be MySQL, HSQL, H2 or anything else, you must specify the relevant jdbc driver so the JPA provider handles things correctly.
You can have multiple data sources and remember you don't have to exhaustive when specifying properties, just set the ones you want.
(a) JSON - conf/openejb.json:
"resources": {
"myMySqlDataSource": {
"properties": {
"JdbcDriver": "com.mysql.jdbc.Driver"
"JdbcUrl": "jdbc:mysql://localhost:8889/myDatabaseName",
"UserName": "root",
"Password": "root",
"JtaManaged": true,
"MaxActive": 200
}
},
"myHsqlDataSource": {
"properties": {
"JdbcDriver": "org.hsqldb.jdbc.JDBCDriver"
"JdbcUrl": "jdbc:hsqldb:mem:myDatabaseName",
"UserName": "root",
"Password": "root",
}
}
}
(b) XML - conf/openejb.xml:
<Resource id="myMySqlDataSource" type="DataSource">
JdbcDriver com.mysql.jdbc.Driver
JdbcUrl jdbc:mysql://localhost:8889/myMysqlDatabaseName
UserName root
Password root
JtaManaged true
MaxActive 200
</Resource>
<Resource id="myHsqlDataSource" type="DataSource">
JdbcDriver org.hsqldb.jdbc.JDBCDriver
JdbcUrl jdbc:hsqldb:mem:myDatabaseName
UserName root
Password root
</Resource>
(c) PROPERTIES - conf/system.properties:
myMySqlDataSource = new://Resource?type=DataSource
myMySqlDataSource.JdbcDriver = org.hsqldb.jdbc.JDBCDriver
myMySqlDataSource.JdbcUrl = jdbc:hsqldb:mem:myHsqlDatabaseName
myMySqlDataSource.UserName = root
myMySqlDataSource.Password = root
myMySqlDataSource.JtaManaged = true
myMySqlDataSource.MaxActive = 200
myHsqlDataSource = new://Resource?type=DataSource
myHsqlDataSource.JdbcDriver = org.hsqldb.jdbc.JDBCDriver
myHsqlDataSource.JdbcUrl = jdbc:hsqldb:mem:myHsqlDatabaseName
myHsqlDataSource.UserName = root
myHsqlDataSource.Password = root
Containers (in the scope of JavaEE) are essentially thread managed services managing your project's beans. These 'beans' are typically your java classes annotated with one of the EJB annotations (such as @Stateless, @Stateful or @Singleton etc.). These containers then provide other classes in your apps one of these beans from a managed pool. This is all lovely in terms of performance, and they can also be configured to be optimized against your system's hardware.
Note that if you don't provide any container settings to OpenEJB, then by default none will get created. So don't go crying when your classes have some @EJB annotated fields waiting to be injected but don't. You got no container to manage your EJBs? then you won't have any injected EJBs. Simple.
There are six types of containers:
- STATELESS: Manages all EJBs annotated with @Stateless
- SINGLETON: Manages all EJBs annotated with @Singleton
- STATEFUL: Manages all EJBs annotated with @Stateful
- MESSAGE_DRIVEN: Manages all EJBs annotated with @MessageDriven
- BMP_ENTITY: TBD
- CMP_ENTITY: TBD
So when it comes to defining your containers, you specify the name/id you want, the type of container it is and some properties.
(a) JSON - conf/openejb.json:
"containers": {
"myStatelessContainer": {
"type": "STATELESS",
"properties": {
"AccessTimeout": "10 seconds"
"MaxSize": 10,
"MinSize": 0,
"StrictPooling": true,
"MaxAge": "0 hours",
"IdleTimeout": "0 minutes"
}
},
"myStatefulContainer": {
"type": "STATEFUL",
"properties": {
"AccessTimeout": "30 seconds",
"TimeOut": 20,
"Frequency": 60,
"Capacity": 1000,
"BulkPassivate": 100
}
},
"mySingletonContainer": {
"type": "SINGLETON",
"properties": {
"AccessTimeout": "30 seconds"
}
}
},
(b) XML - conf/openejb.xml:
<Container id="myStatelessContainer" type="STATELESS">
AccessTimeout = 30 seconds
MaxSize = 10
MinSize = 0
StrictPooling = true
MaxAge = 0 hours
IdleTimeout = 0 minutes
</Container>
<Container id="myStatefulContainer" type="STATEFUL">
AccessTimeout = 30 seconds
TimeOut 20
Frequency 60
Capacity 1000
BulkPassivate 100
</Container>
<Container id="mySingletonContainer" type="SINGLETON">
AccessTimeout = 30 seconds
</Container>
(c) PROPERTIES - con/system.properties:
myStatelessContainer = new://Container?type=Stateless
myStatelessContainer.AccessTimeout = 30 seconds
myStatelessContainer.MaxSize = 10
myStatelessContainer.MinSize = 0
myStatelessContainer.StrictPooling = true
myStatelessContainer.MaxAge = 0 hours
myStatelessContainer.IdleTimeout = 0 minutes
myStatefulContainer = new://Container?type=Stateful
myStatefulContainer.AccessTimeout = 30 seconds
myStatefulContainer.TimeOut = 20
myStatefulContainer.Frequency = 60
myStatefulContainer.Capacity = 1000
myStatefulContainer.BulkPassivate = 100
mySingletonContainer = new://Container?type=Singleton
mySingletonContainer.AccessTimeout = 30 seconds