How to create a EJB 3.x project using Maven in Eclipse – Part 2

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

  1. Create a new Java class “ClientUtility” with package “com.theopentutorials.ejb3” under “src/main/java
  2. 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;
    	}
    }
    	
  3. 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 !!!

Comments
  • Sk.Gouse
    Reply

    can you please explain the same concept using jboss EAP 7.1

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.