JavaEE 6 standardized JNDI naming for EJB local interfaces so there is less guess-work creating local references to other EJBs. However, this spec did not attempt to address remote names. In JavaEE 5, the local and remote JNDI names were vendor-specific but could be overridden with a deployment descriptor to supply a project-specific name. JBoss has removed that custom naming capability and implements a remote name that is based off the local naming standard. The standard uses
The only thing we can change is the name of the items above. In the previous exercise you saw how our default remote JNDI name was as follows.
javaeeExEAR-1.0-SNAPSHOT/javaeeExEJB-1.0-SNAPSHOT/RegistrarEJB!myorg.javaeeex.ejb.RegistrarRemote
The was pretty easy to form within the pom using the following specification in the remote test module.
<!-- adds IT integration tests to the build -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<jndi.name.registrar>javaeeExEAR-${project.version}/javaeeExEJB-${project.version}/RegistrarEJB!myorg.javaeeex.ejb.RegistrarRemote</jndi.name.registrar>
</systemPropertyVariables>
</configuration>
</plugin>There are two issues I have with the above approach.
This exercise is geared at fixing that so that the integration test client code can default to a value like the following.
<jndi.name.registrar>javaeeExEAR/javaeeExEJB/RegistrarEJB!myorg.javaeeex.ejb.RegistrarRemote</jndi.name.registrar>
$ mvn clean install -DskipTests ... [INFO] Java EE Exercise .................................. SUCCESS [0.997s] [INFO] Java EE Exercise EJB .............................. SUCCESS [4.217s] [INFO] Java EE Exercise EAR .............................. SUCCESS [0.909s] [INFO] Java EE Exercise Remote Test ...................... SUCCESS [6.535s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS
$ jar tf javaeeExEAR/target/javaeeExEAR-1.0-SNAPSHOT.ear ... META-INF/application.xml javaeeExEJB-1.0-SNAPSHOT.jar ...
$ jar tf javaeeExEAR/target/javaeeExEAR-1.0-SNAPSHOT.ear
...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC
"-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN"
"http://java.sun.com/dtd/application_1_3.dtd">
<application>
<display-name>javaeeExEAR</display-name>
<description>This project provides a sample EAR for the Java EE components
associated with the overall project.</description>
<module>
<ejb>javaeeExEJB-1.0-SNAPSHOT.jar</ejb>
</module>
</application># javaeeExEAR/pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
<!-- eliminates use of version in EAR JNDI name portion -->
<applicationName>${project.artifactId}</applicationName>
</configuration>
</plugin>
</plugins>
</build># pom.xml
<properties>
...
<maven-ear-plugin.version>2.8</maven-ear-plugin.version>
...
<build>
<pluginManagement>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>${maven-ear-plugin.version}</version>
<configuration>
<version>6</version>
</configuration>
</plugin>$ mvn clean pre-integration-test -rf :javaeeExEAR ... [INFO] Java EE Exercise EAR .............................. SUCCESS [3.519s] [INFO] Java EE Exercise Remote Test ...................... SUCCESS [11.825s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS
# SERVER CONSOLE java:jboss/exported/javaeeExEAR/javaeeExEJB-1.0-SNAPSHOT/RegistrarEJB!myorg.javaeeex.ejb.RegistrarRemote
# javaeeExEAR/target/application.xml
<?xml version="1.0" encoding="UTF-8"?>
<application 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/application_6.xsd" version="6">
<application-name>javaeeExEAR</application-name>
<description>This project provides a sample EAR for the Java EE components
associated with the overall project.</description>
<display-name>javaeeExEAR</display-name>
<module>
<ejb>javaeeExEJB-1.0-SNAPSHOT.jar</ejb>
</module>
</application># javaeeExEAR/pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
<!-- eliminates use of version in EAR JNDI name portion -->
<applicationName>${project.artifactId}</applicationName>
<modules>
<!-- eliminates use of the version in the EJB JNDI name -->
<ejbModule>
<groupId>${project.groupId}</groupId>
<artifactId>javaeeExEJB</artifactId>
<bundleFileName>javaeeExEJB.jar</bundleFileName>
</ejbModule>
</modules>
</configuration>
</plugin># javaeeExEAR/target/application.xml
<?xml version="1.0" encoding="UTF-8"?>
<application 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/application_6.xsd" version="6">
<application-name>javaeeExEAR</application-name>
<description>This project provides a sample EAR for the Java EE components
associated with the overall project.</description>
<display-name>javaeeExEAR</display-name>
<module>
<ejb>javaeeExEJB.jar</ejb>
</module>
</application># SERVER CONSOLE java:jboss/exported/javaeeExEAR/javaeeExEJB/RegistrarEJB!myorg.javaeeex.ejb.RegistrarRemote
private static final String registrarJNDI = System.getProperty("jndi.name.registrar",
"javaeeExEAR/javaeeExEJB/RegistrarEJB!myorg.javaeeex.ejb.RegistrarRemote"); <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>Running myorg.javaeeex.ejbclient.RegistrarIT
-getting jndi initial context
-jndi={java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory, java.naming.provider.url=remote://localhost:4447, java.naming.factory.url.pkgs=,
java.naming.security.principal=known, jboss.naming.client.ejb.context=true, java.naming.security.credentials=password1!}
-jndi name:javaeeExEAR/javaeeExEJB/RegistrarEJB!myorg.javaeeex.ejb.RegistrarRemote
-registrar=Proxy for remote EJB StatelessEJBLocator{appName='javaeeExEAR', moduleName='javaeeExEJB', distinctName='', beanName='RegistrarEJB', view='interface myorg.javaeeex.ejb.RegistrarRemote'}
-*** testPing ***
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.086 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO]
[INFO] --- cargo-maven2-plugin:1.2.3:undeploy (cargo-post) @ javaeeExTest ---
[INFO]
[INFO] --- maven-failsafe-plugin:2.12.2:verify (verify) @ javaeeExTest ---
[INFO] Failsafe report directory: /home/jcstaff/proj/exercises/javaeeEx/javaeeExTest/target/failsafe-reports
...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] Java EE Exercise .................................. SUCCESS [1.005s]
[INFO] Java EE Exercise EJB .............................. SUCCESS [5.544s]
[INFO] Java EE Exercise EAR .............................. SUCCESS [1.372s]
[INFO] Java EE Exercise Remote Test ...................... SUCCESS [10.647s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS. |-- javaeeExEAR | `-- pom.xml |-- javaeeExEJB | |-- pom.xml | `-- src | `-- main | `-- java | `-- myorg | `-- javaeeex | `-- ejb | |-- RegistrarEJB.java | |-- RegistrarLocal.java | `-- RegistrarRemote.java |-- javaeeExTest | |-- pom.xml | `-- src | `-- test | |-- java | | `-- myorg | | `-- javaeeex | | `-- ejbclient | | `-- RegistrarIT.java | `-- resources | |-- jndi.properties | `-- log4j.xml `-- pom.xml
Now that we have a reasonable default value configured into the integration test, we can easily import the project into Eclipse and run the JUnit test in straight Eclipse JUnit.
$ mvn clean pre-integration-test [INFO] --- cargo-maven2-plugin:1.2.3:redeploy (cargo-prep) @ javaeeExTest --- Oct 20, 2012 8:59:04 PM org.xnio.Xnio <clinit> INFO: XNIO Version 3.0.3.GA Oct 20, 2012 8:59:04 PM org.xnio.nio.NioXnio <clinit> INFO: XNIO NIO Implementation Version 3.0.3.GA Oct 20, 2012 8:59:04 PM org.jboss.remoting3.EndpointImpl <clinit> INFO: JBoss Remoting version 3.2.3.GA [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] [INFO] Java EE Exercise .................................. SUCCESS [0.519s] [INFO] Java EE Exercise EJB .............................. SUCCESS [4.862s] [INFO] Java EE Exercise EAR .............................. SUCCESS [1.609s] [INFO] Java EE Exercise Remote Test ...................... SUCCESS [8.883s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS
java.lang.NoClassDefFoundError: Lmyorg/javaeeex/ejb/RegistrarRemote;
at java.lang.Class.getDeclaredFields0(Native Method)
...# javaeeExTest/pom.xml
<!-- brings in the EJB-client jar file w/o the EJB -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>javaeeExEJB</artifactId>
<!-- Eclipse/JUnit cannot resolve types within ejb-client
<type>ejb-client</type>
-->
<type>jar</type>
<version>${project.version}</version>
<scope>test</scope>
</dependency> Since we are so close to this topic I figured I would toss it in as well. Since we can now develop, run, and debug the client inside of Eclipse -- why not the server as well.
# .bin/standalone.conf # Sample JPDA settings for remote socket debugging JAVA_OPTS="$JAVA_OPTS -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"
# .bin/standalone.conf.bat rem # Sample JPDA settings for remote socket debugging set "JAVA_OPTS=%JAVA_OPTS% -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"
# SERVER CONSOLE ========================================================================= Listening for transport dt_socket at address: 8787 17:27:09,991 INFO [org.jboss.modules] JBoss Modules version 1.1.1.GA
# javaeeExEJB/src/main/java/myorg/javaeeex/ejb/RegistrarEJB.java
public void ping() {
log.debug("ping called");
} # SERVER CONSOLE Listening for transport dt_socket at address: 8787
We configured these values using the maven-ear-plugin -- which ultimately created the application.xml according to our definition.
We also tacked on some ease-of-use issues aspects with importing and running the JUnit test within Eclipse as well as performing a remote debugging session to complete the Eclipse topic.