Enterprise Java Development@TOPIC@
EJBs are based on Plain Old Java Objects (POJOs)
Standard POJO rules apply...
...
public class GreeterEJB implements Greeter {
private static final Logger logger = LoggerFactory.getLogger(GreeterEJB.class);
...
}
Must not write to static fields. Read-only static fields are allowed (suggests use of final)
Must not use thread synchronization primitives to synchronize execution
Must not manage/manipulate threads, class loaders, or security managers
Must not attempt to become a network server and form a network listen and similar actions
...
@Override
public String sayHello(String name) throws BadRequestException {
logger.debug("sayHello({})", name);
if (name == null || name.isEmpty()) {
throw new BadRequestException("you must have a name for me to say hello");
}
return "hello " + name;
}
Normal stateless POJO method at this point
import info.ejava.examples.ejb.basic.dto.Greeting;
import info.ejava.examples.ejb.basic.dto.Name;
public interface Greeter {
String sayHello(String name) throws BadRequestException;
Greeting sayHello(Name name) throws BadRequestException;
}
Provides an abstraction of the public class business methods
Some methods use simple/primitive types. Others use complex/custom classes.
All types conveniently defined using Serializable types at this point to permit use of remote interface in future
public class Name implements Serializable {
private String firstName;
private String lastName;
...
public class Greeting implements Serializable {
private Date date;
private String message;
...
Data abstraction necessary for local and remote interaction
Serializable not necessary until we use this in a remote interface
import static org.junit.Assert.*;
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.Greeter;
import info.ejava.examples.ejb.basic.ejb.GreeterEJB;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GreeterTest {
private static final Logger logger = LoggerFactory.getLogger(GreeterTest.class);
private Greeter greeter;
@Before
public void setUp() {
greeter = new GreeterEJB();
}
...
}
Test case used to verify the core functionality of the POJO -- prior to deployment as EJB
Each test case should be independent of another and not depend on a particular order
@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()));
}
Each test method focused on testing a specific scenario or state
Contains assert statements to verify expected results
Each test method should be independent of another and not depend on a particular order
Production classes typically deployed in a Java archive (JAR)
$ jar tf target/ejb-basic-ejb-4.0.0-SNAPSHOT.jar ... info/ejava/examples/ejb/basic/ejb/BadRequestException.class info/ejava/examples/ejb/basic/ejb/Greeter.class info/ejava/examples/ejb/basic/ejb/GreeterEJB.class info/ejava/examples/ejb/basic/dto/Name.class info/ejava/examples/ejb/basic/dto/Greeting.class ...
|-- pom.xml `-- src |-- main | `-- java | `-- info | `-- ejava | `-- examples | `-- ejb | `-- basic | |-- dto | | |-- Greeting.java | | `-- Name.java | `-- ejb | |-- BadRequestException.java | |-- GreeterEJB.java | `-- Greeter.java `-- test |-- java | `-- info | `-- ejava | `-- examples | `-- ejb | `-- basic | `-- pojo | `-- GreeterTest.java `-- resources `-- log4j.xml
Module contains separate source trees for production and unit test code
Unit tests should run with every module build
Unit tests should auto-evaluate themselves so that no human analysis is required
$ mvn clean test ... [INFO] Deleting .../ejb-basic-ejb/target [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ ejb-basic-ejb --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory .../ejb-basic-ejb/src/main/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ ejb-basic-ejb --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 5 source files to .../ejb-basic-ejb/target/classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ ejb-basic-ejb --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ ejb-basic-ejb --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to .../ejb-basic-ejb/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:2.17:test (default-test) @ ejb-basic-ejb --- [INFO] Surefire report directory: .../ejb-basic-ejb/target/surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running info.ejava.examples.ejb.basic.pojo.GreeterTest 16:57:12,237 INFO (GreeterTest.java:41) -*** dto *** 16:57:12,243 DEBUG (GreeterEJB.java:41) -sayHello(Name [firstName=thing, lastName=one]) 16:57:12,249 INFO (GreeterTest.java:27) -*** pojoGreeter *** 16:57:12,250 DEBUG (GreeterEJB.java:27) -sayHello(cat inhat) 16:57:12,252 INFO (GreeterTest.java:35) -*** badName *** 16:57:12,255 DEBUG (GreeterEJB.java:27) -sayHello() Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.239 sec - in info.ejava.examples.ejb.basic.pojo.GreeterTest Results : Tests run: 3, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.815 s ...
Basic POJO/JAR pom thus far
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>info.ejava.examples.ejb.basicejb</groupId>
<artifactId>ejb-basic-ejb</artifactId>
<packaging>jar</packaging>
<dependencies>
<!-- core implementation dependencies -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>