In Part 1 of this tutorial, we saw how to develop and deploy EJB in JBoss AS using Maven in Eclipse. In this EJB Maven tutorial we will see how to develop and run the EJB client (using Maven) to access the ejb.
Create New Maven Project in Eclipse
- Open Eclipse IDE and create a new Maven project which can be done in three ways,
- Right click on Project Explorer -> New -> Other… -> Maven -> Maven Project
- File menu -> New -> Other… -> Maven -> Maven Project
- Click on the down arrow on New icon on toolbar -> Other… -> Maven -> Maven Project
- Select Maven Project and click Next.
- This screen prompts for project workspace location. Make sure “Use default Workspace location” and “Create a simple project (skip archetype selection)” are selected and click Next.
- Now we have to configure the project by entering the following details and click Finish.
- Enter Group Id: as “com.theopentutorials.ejb3.client“
- Enter Artifact Id as “ejbclientmavendemo“
- Enter Version: as “1.0-SNAPSHOT“
- Packaging: jar
- Name: EJB3 Client Maven
Create EJB3 client
- Create a new Java class “ClientUtility” with package “com.theopentutorials.ejb3” under “src/main/java”
- Copy paste the following code.
package com.theopentutorials.ejb3; import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; public class ClientUtility { private static Context initialContext; private static final String PKG_INTERFACES = "org.jboss.ejb.client.naming"; public static Context getInitialContext() throws NamingException { if (initialContext == null) { Properties properties = new Properties(); properties.put(Context.URL_PKG_PREFIXES, PKG_INTERFACES); initialContext = new InitialContext(properties); } return initialContext; } }
- Now create another Java class “Client” in the same package and copy the following code.
package com.theopentutorials.ejb3; import javax.naming.Context; import javax.naming.NamingException; import com.theopentutorials.ejb3.HelloWorld; public class Client { public static void main(String[] args) { HelloWorld bean = doLookup(); System.out.println(bean.sayHello()); // 4. Call business logic } private static HelloWorld doLookup() { Context context = null; HelloWorld bean = null; try { // 1. Obtaining Context context = ClientUtility.getInitialContext(); // 2. Generate JNDI Lookup name String lookupName = getLookupName(); // 3. Lookup and cast bean = (HelloWorld) context.lookup(lookupName); } catch (NamingException e) { e.printStackTrace(); } return bean; } private static String getLookupName() { /* * The app name is the EAR name of the deployed EJB without .ear suffix. * Since we haven't deployed the application as a .ear, the app name for * us will be an empty string */ String appName = ""; /* * The module name is the JAR name of the deployed EJB without the .jar * suffix. */ String moduleName = "ejbmavendemo-1.0-SNAPSHOT"; /* * AS7 allows each deployment to have an (optional) distinct name. This * can be an empty string if distinct name is not specified. */ String distinctName = ""; // The EJB bean implementation class name String beanName = "HelloWorldBean"; // Fully qualified remote interface name final String interfaceName = "com.theopentutorials.ejb3.HelloWorld"; // Create a look up string name String name = "ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + interfaceName; return name; } }
EJB3 client pom.xml
Copy paste the following in your pom.xml file.
<?xml version="1.0"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.theopentutorials.ejb3.client</groupId> <artifactId>ejbclientmavendemo</artifactId> <version>1.0-SNAPSHOT</version> <name>EJB3 Client Maven</name> <packaging>jar</packaging> <properties> <!-- Explicitly declaring the source encoding eliminates the following message: --> <!-- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- JBoss dependency versions --> <version.org.jboss.as>7.1.1.Final</version.org.jboss.as> <version.org.jboss.as.plugins.maven.plugin>7.3.Final</version.org.jboss.as.plugins.maven.plugin> <version.org.jboss.spec.jboss.javaee.6.0>3.0.0.Final</version.org.jboss.spec.jboss.javaee.6.0> <!-- other plugin versions --> <version.compiler.plugin>2.3.1</version.compiler.plugin> <version.exec.plugin>1.2.1</version.exec.plugin> <!-- maven-compiler-plugin --> <maven.compiler.target>1.6</maven.compiler.target> <maven.compiler.source>1.6</maven.compiler.source> </properties> <dependencyManagement> <dependencies> <!-- Define the version of JBoss' Java EE 6 APIs we want to use --> <!-- JBoss distributes a complete set of Java EE 6 APIs including a Bill of Materials (BOM). A BOM specifies the versions of a "stack" (or a collection) of artifacts. We use this here so that we always get the correct versions of artifacts. Here we use the jboss-javaee-6.0 stack (you can read this as the JBoss stack of the Java EE 6 APIs). You can actually use this stack with any version of JBoss AS that implements Java EE 6, not just JBoss AS 7! --> <dependency> <groupId>org.jboss.spec</groupId> <artifactId>jboss-javaee-6.0</artifactId> <version>${version.org.jboss.spec.jboss.javaee.6.0}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-ejb-client-bom</artifactId> <version>${version.org.jboss.as}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- Import the transaction spec API, we use runtime scope because we aren't using any direct reference to the spec API in our client code --> <dependency> <groupId>org.jboss.spec.javax.transaction</groupId> <artifactId>jboss-transaction-api_1.1_spec</artifactId> <scope>runtime</scope> </dependency> <!-- Import the EJB 3.1 API, we use runtime scope because we aren't using any direct reference to EJB spec API in our client code --> <dependency> <groupId>org.jboss.spec.javax.ejb</groupId> <artifactId>jboss-ejb-api_3.1_spec</artifactId> <scope>runtime</scope> </dependency> <!-- We depend on the EJB remote business interfaces of this application --> <dependency> <groupId>com.theopentutorials.ejb3</groupId> <artifactId>ejbmavendemo</artifactId> <type>ejb-client</type> <version>${project.version}</version> </dependency> <!-- JBoss EJB client API jar. We use runtime scope because the EJB client API isn't directly used in this example. We just need it in our runtime classpath --> <dependency> <groupId>org.jboss</groupId> <artifactId>jboss-ejb-client</artifactId> <scope>runtime</scope> </dependency> <!-- client communications with the server use XNIO --> <dependency> <groupId>org.jboss.xnio</groupId> <artifactId>xnio-api</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.jboss.xnio</groupId> <artifactId>xnio-nio</artifactId> <scope>runtime</scope> </dependency> <!-- The client needs JBoss remoting to access the server --> <dependency> <groupId>org.jboss.remoting3</groupId> <artifactId>jboss-remoting</artifactId> <scope>runtime</scope> </dependency> <!-- Remote EJB accesses can be secured --> <dependency> <groupId>org.jboss.sasl</groupId> <artifactId>jboss-sasl</artifactId> <scope>runtime</scope> </dependency> <!-- data serialization for invoking remote EJBs --> <dependency> <groupId>org.jboss.marshalling</groupId> <artifactId>jboss-marshalling-river</artifactId> <scope>runtime</scope> </dependency> </dependencies> <build> <plugins> <!-- Enforce Java 1.6 --> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>${version.compiler.plugin}</version> <configuration> <source>${maven.compiler.source}</source> <target>${maven.compiler.target}</target> </configuration> </plugin> <!-- Add the maven exec plugin to allow us to run a java program via maven --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>${version.exec.plugin}</version> <executions> <execution> <goals> <goal>exec</goal> </goals> </execution> </executions> <configuration> <executable>java</executable> <workingDirectory>${project.build.directory}/exec-working-directory</workingDirectory> <arguments> <!-- automatically creates the classpath using all project dependencies, also adding the project build directory --> <argument>-classpath</argument> <classpath> </classpath> <argument>com.theopentutorials.ejb3.Client</argument> </arguments> </configuration> </plugin> </plugins> </build> </project>
Maven Plugins used
1. maven-compiler-plugin
The maven-compiler-plugin is used to compile the sources of your project. We specified jdk 1.6 version for source and target classes.
2. exec-maven-plugin
Since our ejb client is a Java program, to run it we use the exec-maven-plugin which helps to execute system and Java programs. We need to specify the executable (i.e. java), classpath, and the java class (com.theopentutorials.ejb3.Client). The classpath is left empty because the plugin includes the necessary classpath arguments based on the dependencies provided.
Maven Dependencies for EJB3 client
In order to run EJB3 client we need to include the following dependencies,
- We depend on the EJB remote business interfaces of this application to run the client. So we need to specify the ejb client jar dependency. The <type> tag with value “ejb-client” is used to specify this project’s dependency on the EJB client jar.
<dependency> <groupId>com.theopentutorials.ejb3</groupId> <artifactId>ejbmavendemo</artifactId> <type>ejb-client</type> <version>${project.version}</version> </dependency>
- The dependencies jboss-transaction-api_1.1_spec, jboss-ejb-api_3.1_spec, jboss-ejb-client, xnio-api, xnio-nio, jboss-remoting, jboss-sasl, jboss-marshalling-river have scope as runtime because these are all not required for compilation.
- The dependencies jboss-javaee-6.0 and jboss-as-ejb-client-bom under dependencyManagement have scope as import which is used to include dependency management information from a remote POM into the current project. These remote POMs are provided by JBoss which contains the necessary dependencies for running the client.
JBoss EJB Client properties
- Create a file under “src/main/resources” and name it as “jboss-ejb-client.properties”
- Copy paste the following code.
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port = 4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
Project Structure
Run the project
- If the project shows any error update the project by right clicking the project, Maven -> Update Project
- Then go to your pom.xml, right-click, select Run As -> Maven build
- Specify the goal as exec:exec (provided by exec-maven-plugin)
Output
If there are no errors, you should see the following output.
Hello World !!!
can you please explain the same concept using jboss EAP 7.1