1.Generally speaking the only way to get a Container-Managed Resource is via dependency injection or lookup from within a Container-Managed Component.
2. Singleton
a.Singletons have an '@Startup' annotation which can be applied to the bean class. When used, the Container will instantiate the Singleton instance eagerly when the application start up, otherwise the Container will instantiate the Singleton instance lazily when the bean is first accessed.
@DependsOn({"SingletonB", "SingletonC"})
@Singleton
@Startup
public class SingletonA {
...
}
b.Note that @DependsOn is only required(and should only be used) if a Singleton uses another Singleton in its @PostConstruct method or @PreDestory method. Simply having a reference to another Singleton and using it in other business methods does not require an @DependsOn declaration.
3. Containers
a.CMP_ENTITY
1.openejb.xml
<Container id="Foo" type="CMP_ENTITY">
</Container>
2.properties file
Foo=new://Container?type=CMP_ENTITY
3.property
CmpEngineFactory - org.apache.openejb.core.cmp.jpa.JpaCmpEngineFactory
b.BMP_ENTITY
1.openejb.xml
<Container id="Foo" type="BMP_ENTITY">
</Container>
2.properties file
Foo=new://Container?type=BMP_ENTITY
3.property
PoolSize - 10
c.STATELESS
1.openejb.xml
<Container id="Foo" type="STATELESS">
</Container>
2.properties file
Foo=new://Container?type=STATELESS
3.property
Timeout - 0 millisecond
PoolSize - 10
StrictPooling - true
d.STATEFUL
1.openejb.xml
<Container id="Foo" type="STATELESS">
</Container>
2.properties file
Foo=new://Container?type=STATEFUL
3.property
Passivator - org.apache.openejb.core.stateful.RAFPassivater
- org.apache.openejb.core.stateful.Simplepassivater(default)
TimeOut - 20 minutes
PoolSize - 1000
BulkPassivate - 100
e.MESSAGE
1.openejb.xml
<Container id="Foo" type="MESSAGE">
</Container>
2.properties file
Foo=new://Container?type=MESSAGE
3.property
ResourceAdapter - The resource adapter delivers messages to the container. Default value is Default JMS Resource Adapter
MessageListenerInterface - Specifies the message listener interface handled by this container. Default value is javax.jms.MessageListener.
ActivationSepcClass - Specifies the activation spec class. Default value is org.apache.activemq.ra.ActionMQActivationSpec.
instanceLimit - Specifies the maximum number of bean instances that are allowed to exists for each MDB deployment. Default value is 10.
f.Resource
1.javax.sql.DataSource
<Resource id="Foo" type="javax.sql.DataSource">
</Resource>
Foo=new://Resource?type=javax.sql.DataSource
properties:JtaManaged, JdbcDriver, JdbcUrl, UserName, Password, ConnectionProperties, DefaultAutoCommit, DefaultReadOnly, DefaulTransactionIsolation, InitialSize, MaxActive, maxIdle, MinIdle, MaxWait, ValidationQuery, TestOnBorrow, TestOnReturn, TestWhileIdle, TimeBetweenEvictionRunsMillis, NumTestsPerEvictionRun, MinEvictableIdleTimeMillis, PoolPreparedStatements, MaxOpenPreparedStatements, AccessToUnderlyingConnectionAllowed
2.ActiveMQResourceAdapter
<Resource id="Foo" type="ActiveMQResourceAdapter">
</Resource>
Foo=new://Resource?type=ActiveMQResourceAdapter
properties:
BrokerXmlConfig - broker:(tcp://localhost:61616)?useJmx=false
ServerUrl - vm://localhost?async=true
DataSource - Default value is Default Unmanaged JDBC Database
3.javax.jms.ConnectionFactory
<Resource id="Foo" type="javax.jms.ConnectionFactory">
</Resource>
Foo = new://Resource?type=javax.jms.ConnectionFactory
properties:
ResourceAdapter
TransactionSupport
PoolMaxSize
PoolMinSize
ConnectionMaxWaitMilliseconds
ConnectionMaxIdleMinutes
4.javax.jms.Queue
<Resource id="Foo" type="javax.jms.Queue">
</Resource>
Foo = new://Resource?type=javax.jms.Queue
properties:
destination - Specifies the name of the queue
5.javax.jms.Topic
<Resource id="Foo" type="javax.jms.Topic">
</Resource>
Foo = new://Resource?type=javax.jms.Topic
properties:
destination - Specifies the name of the topic
6.org.omg.CORBA.ORB
<Resource id="Foo" type="org.omg.CORBA.ORB">
</Resource>
Foo = new://Resource?type=org.omg.CORBA.ORB
7.javax.mail.Session
<Resource id="Foo" type="javax.mail.Session">
</Resource>
Foo = new://Resource?type=javax.mail.Session
4. Configuring Datasource
@Resource(name = "myDerbyDatasource", type = javax.sql.DataSource.class)
<Resource id="myDerbyDatasource" type="javax.sql.DataSource">
. . . .
<Resource>
5. JNDI names for configured DataSources
<Resource id="Default JDBC Database" type="DataSource">
. . . . .
</Resource>
The global jndi name would be java:openejb/Resource/Default JDBC Database
6. Obtaining a DataSource
DataSource references in your EJB should get automatically mapped to the Resource you declare. The shortest and easiest rule is that 'if your reference name matches a Resource in you openejb.xml, that's the one you get'. Essentially, the rules for mapping are as follows:
1. Name Attribute Match - @Resource with a name attribute matching the resource name gets that resource injected
2. Injected Name Match - variable name matching the resource name gets that resource injected
3. No Match - nothing matches a resource name, so the first resource available gets injected
e.g.:
Resource:
<Resource id="myDerbyDatabase" type="DataSource">
. . . . .
</Resource>
a. BY matching variable name to resource name:
@Stateless
public class FooBean {
@Resource DataSource myDerbyDatabase;
}
b. BY matching name
@Stateless
public class FooBean {
@Resource(name="myDerbyDatabase")
DataSource dataSource;
}
c. BY JNDI lookup
@Resource(name="myDerbyDatabase", type=javax.sql.DataSource.class)
@Stateless
public class FooBean {
public void setSessionContext(SessionContext sessionContext) {
DataSource dataSource = (DataSource) sessionContext.lookup("myDerbyDatabase");
}
public void someOtherMethod() throws Exception {
InitialContext initialContext = new InitialContext();
DataSource dataSource = (DataSource) initialContext.lookup("java:comp/env/myDerbyDatabase");
}
}
<resource-ref>
<res-ref-name>myDerbyDatabase</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
</resource-ref>
<resource-ref>
<res-ref-name>jdbc/myDerbyDatabase</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
</resource-ref>
<resource-ref>
<res-ref-name>someOtherName</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<mapped-name>myDerbyDatabase</mapped-name>
</resource-ref>
7. Working with OpenJPA
a.jndi.properties
java.naming.factory.initial=org.apache.openejb.client.LocalInitialContextFactory
java.naming.provider.url=ejbd://localhost:4201
oracleDatabase=new://Resource?type=DataSource
oracleDatabase.JdbcDriver=oracle.jdbc.driver.OracleDriver
oracleDatabase.JdbcUrl=jdbc:oracle:thin:@10.199.130.142:1521:apj
oracleDatabase.UserName=trs
oracleDatabase.Password=trs
b.persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="oracle">
<jta-data-source>oracleDatabase</jta-data-source>
<properties>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" /> <!-- auto_ddl=true -->
<property name="openjpa.Log" value="SQL=TRACE" /> <!-- print SQL -->
<property name="openjpa.ConnectionFactoryProperties" value="PrettyPrint=true, PrettyPrintLineLength=80" /> <!-- pretty print SQL -->
</properties>
</persistence-unit>
</persistence>
c.ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
version="3.0">
<display-name>ejb3</display-name>
</ejb-jar>
d.PersistenceContext injection
@PersistenceContext(unitName = "oracle")
protected EntityManager entityManager;
e.EJBTest.java
import java.io.IOException;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.junit.Before;
public abstract class EJBTest {
private InitialContext ctx;
public EJBTest() {
}
@Before
public void initialise() {
final Properties props = new Properties();
try {
props.load(Thread.currentThread().getContextClassLoader()
.getResourceAsStream("ejb-test-configure.properties"));
this.ctx = new InitialContext(props);
this.init();
} catch (NamingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
protected <T> T getEJBBean(final Class<T> clz) {
final String jndiName = clz.getSimpleName() + "ImplRemote";
return this.getEJBBean(jndiName);
}
@SuppressWarnings("unchecked")
protected <T> T getEJBBean(final String jndiName) {
T bean = null;
try {
bean = (T) this.ctx.lookup(jndiName);
} catch (NamingException e) {
e.printStackTrace();
}
return bean;
}
public abstract void init();
}
8. EJB bean lifecycle
a.stateless: new instance() -> dependency inject -> PostConstruct callback -> application invocation -> PreDestory callback;
b.stateful: new instance() -> dependency inject -> PostConstruct callback -> ready status(app invoke) -> PrePassivate(opt.) -> Passive status -> PostActivate(opt.) -> ready status -> PreDestroy
c.entity: new() -> new -> persist() -> managed -> remove() -> removed ->persist() -> managed -> persistence context ends -> detached -> merge() -> managed -> refresh() -> managed.
9. Setting jndi name pattern in OpenEJB
a.put properties - openejb.jndiname.format={interfaceClass} in {OpenEJB_HOME}/conf/system.properties(create it if not existing)
10. Setting Oracle datasource
a.add 'Resource' in openejb.xml;
<Resource id="oracleDS" type="DataSource">
JdbcDriver oracle.jdbc.driver.OracleDriver
JdbcUrl jdbc:oracle:thin:@10.199.130.142:1521:apj
UserName trs
Password trs
JtaManaged true
</Resource>
b.copy the ojdbc14.jar to {OpenEJB_HOME}/lib/;
c.refer to the 'Resource' in persistence.xml;
<persistence-unit name="oracle" transaction-type="JTA">
<jta-data-source>oracleDS</jta-data-source>
<properties>
<property name="openjpa.Log" value="SQL=TRACE" />
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
</properties>
</persistence-unit>
11. setting deploy folders / projects:
<Deployments dir="apps/" />
<Deployments dir="c:\my\app\beans\" />
<Deployments jar="c:\my\app\superEjbs.jar" />