Enterprise Java Development@TOPIC@
Unit tests test POJO classes in a single Maven phase
IT tests test components deployed to the server using multiple phases Maven Lifecycle Reference
pre-integration-test
Deploy artifacts
integration-test
Execute tests
post-integration-test
Undeploy artifacts
verify
Evaluate test results (possibly fail build after artifacts undeployed)
IT tests require remote access
Access Type
JBoss Remoting
EJB Client
JNDI Properties
JNDI Name
IT tests test EJB deployed to server
Java client may access @Remote interface of EJB by first going through Java Naming and Directory Interface (JNDI)
JBoss uses two different types of remote interface techniques -- both accessed thru JNDI; JBoss Remoting and EJB Client
Obtain JNDI properties through combination of jndi.properties file and supplied Properties object.
java.util.Properties jndiProperties=...; // varies whether using Remoting or EJBClient
|-- jndi.properties java.naming.factory.initial=... java.naming.factory.url.pkgs=... java.naming.provider.url=...
Get InitialContext to server JNDI tree
Context jndi = new InitialContext(jndiProperties); //jndi.properties augmented
Context jndi = new InitialContext(); //jndi.properties is complete
Obtain JNDI-name using deployment-specific name and access technique
String jndiName; // varies whether accessing EJB, WAR or EAR deployment and access
Lookup EJB's remote interface
GreeterRemote greeter = (GreeterRemote) jndi.lookup(jndiName);
Legacy approach
Follows published standards
Consistent with other resource types (e.g., JMS resource lookups)
Knows nothing of EJB
Stated to be less efficient than EJB Client
java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory java.naming.factory.url.pkgs= java.naming.provider.url=http-remoting://localhost:8080 jboss.naming.client.ejb.context=true
Custom API for accessing EJBs
Can perform certain actions more efficiently with that knowledge and specialization
Uses separate naming context (ejb:)
Uses different and separate properties
Specifics can be shielded from client with minimal effort
java.naming.factory.initial= java.naming.factory.url.pkgs=org.jboss.ejb.client.naming java.naming.provider.url=
#top level property listing the names of the connections remote.connections=default #here we define the properties for the server we have called "default" remote.connection.default.host=localhost remote.connection.default.port=8080 remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
ejb:/ejb-basic-ejb/GreeterEJB!info.ejava.examples.ejb.basic.ejb.GreeterRemote
ejb:/ejb-basic-war/GreeterEJB!info.ejava.examples.ejb.basic.ejb.GreeterRemote
ejb:ejb-basic-ear/ejb-basic-ejb/GreeterEJB!info.ejava.examples.ejb.basic.ejb.GreeterRemote
The EJB Client implementation understands JBoss/Wildfly EJBs and to further help optimize the communication with Stateful Session EJBs the following string ("?stateful")must be appended to the JNDI name
InitialContextFactory looks for custom naming extensions when encountering naming prefix ("ejb:")
java.naming.factory.url.pkgs lists base package names to start looking for extensions
jboss-ejb-client.jar must be in the classpath
$ mvn dependency:tree [INFO] +- info.ejava.examples.common:jboss-rmi-client:pom:4.0.0-SNAPSHOT:test [INFO] | +- org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec:jar:1.0.0.Final:test [INFO] | +- org.jboss.spec.javax.ejb:jboss-ejb-api_3.2_spec:jar:1.0.0.Final:test [INFO] | +- org.jboss:jboss-ejb-client:jar:2.0.1.Final:test
Provider looks for "ejb" extension below "org.jboss.ejb.client.naming" package
#jndi.properties java.naming.factory.url.pkgs=org.jboss.ejb.client.naming
$ jar tf ~/.m2/repository/org/jboss/jboss-ejb-client/2.0.1.Final/jboss-ejb-client-2.0.1.Final.jar | grep org.jboss.ejb.client.naming ... org/jboss/ejb/client/naming/ejb/SecurityActions$1.class org/jboss/ejb/client/naming/ejb/EjbNamingContext$2.class org/jboss/ejb/client/naming/ejb/EjbNamingContext.class org/jboss/ejb/client/naming/ejb/EjbNamingContextSetup.class org/jboss/ejb/client/naming/ejb/ejbURLContextFactory.class org/jboss/ejb/client/naming/ejb/SecurityActions.class org/jboss/ejb/client/naming/ejb/EjbJndiIdentifier.class org/jboss/ejb/client/naming/ejb/EjbJndiNameParser.class org/jboss/ejb/client/naming/ejb/SecurityActions$2.class org/jboss/ejb/client/naming/ejb/SecurityActions$3.class org/jboss/ejb/client/naming/ejb/EjbNamingContext$1.class
EJB Client only works for EJBs
InitialContext may need to locate other non-EJB resources (e.g., JMS)
Replace default InitialContextFactory with JBoss Remoting
Extend JBoss Remoting InitialContextFactory with EJB Client
java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory java.naming.factory.url.pkgs=org.jboss.ejb.client.naming java.naming.provider.url=http-remoting://localhost:8080 jboss.naming.client.ejb.context=true
IT tests require...
Server running (possibly started)
EJB deployed
Tests run
EJB undeployed (proper cleanup)
Server stopped (if started as part of the test)
Results evaluated
IT test can also be written with JUnit
@BeforeClass runs at start of test case and before all test methods. This must be public and static
@Before runs before each test method. This must be public and non-static
@After runs after each test method. This must be public and non-static
@AfterClass runs after all test methods are complete and prior to test case shutdown. This must be public and static
...
import static org.junit.Assert.*;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import info.ejava.examples.ejb.basic.dto.Greeting;
import info.ejava.examples.ejb.basic.dto.Name;
import info.ejava.examples.ejb.basic.ejb.BadRequestException;
import info.ejava.examples.ejb.basic.ejb.GreeterRemote;
...
public class GreeterIT {
private static final Logger logger = LoggerFactory.getLogger(GreeterBase.class);
protected Properties jndiProperties; // varies whether using Remoting or EJBClient
protected String jndiName; // varies whether accessing EJB, WAR or EAR deployment and access
protected Context jndi;
protected GreeterRemote greeter;
@Before
public void setUp() throws Exception {
jndi = new InitialContext(jndiProperties);
greeter = (GreeterRemote) jndi.lookup(jndiName);
}
@After
public void tearDown() throws Exception {
if (jndi != null) {
jndi.close(); // produces errors with JBoss Remoting
}
}
@Before method sets up JNDI context and performs lookup for @Remote before each @Test
@After method closes out JNDI Context between @Tests
Same as before except they must use the EJB remote interface rather than instantiate bean
@Test
public void pojoGreeter() throws BadRequestException {
logger.info("*** pojoGreeter ***");
String name = "cat inhat";
String greeting = greeter.sayHello(name);
assertTrue("greeter did not say my name", greeting.contains(name));
}
@Test(expected = BadRequestException.class)
public void badName() throws BadRequestException {
logger.info("*** badName ***");
greeter.sayHello("");
}
@Test
public void dto() throws BadRequestException {
logger.info("*** dto ***");
Name name = new Name("thing", "one");
Greeting greeting = greeter.sayHello(name);
assertTrue("greeter did not say my name", greeting.getGreeting()
.contains(name.getFirstName()));
}
IT tests housed in separate modules (can be part of EJB and WAR modules)
jndi.properties part of IT test tree -- not the production code
. |-- pom.xml `-- src `-- test |-- java | `-- info | `-- ejava | `-- examples | `-- ejb | `-- basicejb | `-- ejbclient | |-- GreeterIT.java `-- resources |-- jboss-ejb-client.properties |-- jndi.properties `-- log4j.xml
surefire/Unit Tests run prior to deployment
failsafe/IT tests run after deployment
$ mvn clean verify ... [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ ejb-basic-test --- [INFO] Deleting .../ejb-basic-example/ejb-basic-test/target ... [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ ejb-basic-test --- [INFO] No sources to compile [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ ejb-basic-test --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 4 resources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ ejb-basic-test --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 5 source files to .../ejb-basic-example/ejb-basic-test/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:2.17:test (default-test) @ ejb-basic-test --- [INFO] [INFO] --- maven-jar-plugin:2.5:jar (default-jar) @ ejb-basic-test --- [WARNING] JAR will be empty - no content was marked for inclusion! [INFO] Building jar: .../ejb-basic-example/ejb-basic-test/target/ejb-basic-test-4.0.0-SNAPSHOT.jar ... [INFO] --- cargo-maven2-plugin:1.4.3:redeploy (cargo-prep) @ ejb-basic-test --- Sep 28, 2014 11:58:23 PM org.xnio.Xnio <clinit> INFO: XNIO version 3.2.2.Final Sep 28, 2014 11:58:23 PM org.xnio.nio.NioXnio <clinit> INFO: XNIO NIO Implementation Version 3.2.2.Final Sep 28, 2014 11:58:23 PM org.jboss.remoting3.EndpointImpl <clinit> INFO: JBoss Remoting version 4.0.3.Final ... [INFO] --- maven-failsafe-plugin:2.17:integration-test (integration-tests) @ ejb-basic-test --- [INFO] Failsafe report directory: .../ejb-basic-example/ejb-basic-test/target/failsafe-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running info.ejava.examples.ejb.basicejb.ejbclient.GreeterRemotingWARIT 23:58:26,441 INFO (GreeterIT.java:43) -using jndiName=ejb-basic-war/GreeterEJB!info.ejava.examples.ejb.basic.ejb.GreeterRemote ... 23:58:27,811 INFO (GreeterIT.java:43) -using jndiName=ejb:ejb-basic-ear/ejb-basic-ejb/GreeterEJB!info.ejava.examples.ejb.basic.ejb.GreeterRemote ... 23:58:28,167 INFO (GreeterIT.java:43) -using jndiName=ejb-basic-ear/ejb-basic-ejb/GreeterEJB!info.ejava.examples.ejb.basic.ejb.GreeterRemote ... 23:58:28,289 INFO (GreeterIT.java:43) -using jndiName=ejb:/ejb-basic-war/GreeterEJB!info.ejava.examples.ejb.basic.ejb.GreeterRemote Results : Tests run: 12, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] --- cargo-maven2-plugin:1.4.3:undeploy (cargo-post) @ ejb-basic-test --- [INFO] [INFO] --- maven-failsafe-plugin:2.17:verify (verify) @ ejb-basic-test --- [INFO] Failsafe report directory: .../ejb-basic-example/ejb-basic-test/target/failsafe-reports [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 11.036 s