EJB – pt1

All

EJB

EJB is deployed in Jar, War, Ear format. In WAR, if the EJB is packaged in jar format, it can be placed in WEB-INF/lib. If EJB classes are to be directly packaged in WAR, they can placed in WEB-INF/classes.

I will create a minimal project here to show a client accessing a Stateless bean (basically a simplified version from quickstart) and code on Github.

1. Create the project:

For this you need a home interface/remote interface and the implementation, as explained here:

1.a Create an interface

import javax.ejb.Remote;
@Remote
public interface SumRemote
{ int add(int a, int b); }

1.b Implement this interface

import javax.ejb.Stateless;

@Stateless
public class Sum implements SumRemote
{ public int add(int a, int b){ return a+b; } }

1.c Create a client (eap 7.1:)

Get the InitialContext:

public static Context getInitialContext() throws NamingException{
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, “org.wildfly.naming.client.WildFlyInitialContextFactory”);
props.put(Context.PROVIDER_URL,”remote+http://localhost:8080“);
final Context context = new InitialContext(props);
return context;

(The port here comes from <socket-binding name=”http” port=”${jboss.http.port:8080}”/>)

And then get the remote – attention that is stateless so the JNDI will be:

The class name we know, is SumRemote, so we can add it diretly, or use the .class.getName(0;

SumRemote remote = (SumRemote) getInitialContext().lookup(“ejb:/EjbSum/Sum!” + SumRemote.class.getName());

OR

AdderImplRemote remote = (AdderImplRemote) getInitialContext().lookup(“ejb:/EjbRemote/Sum!SumRemote”);

2. Export

JBOSS_HOME/modules/system/layers/base/javax/ejb/api/main/jboss-ejb-api_3.2_spec-1.0.1.Final-redhat-1.jar

3. Compile and package:

[fdemeloj@fdemeloj Bean]$ javac Sum*

[fdemeloj@fdemeloj Bean]$ jar -cvf EjbSum.jar .
added manifest
adding: SumRemote.class(in = 194) (out= 163)(deflated 15%)
adding: Sum.class(in = 335) (out= 253)(deflated 24%)

Compile the Client

#export CLASSPATH=/home/fdemeloj/jboss-eap-7.3/bin/client/jboss-client.jar:$CLASSPATH
#javac StandaloneClient.java

4.Deploy

[fdemeloj@fdemeloj Bean]$ cp EjbSum.jar $JBOSS_HOME/standalone/deployments

This is the JNDI:

23:17:47,545 INFO [org.jboss.as.ejb3.deployment] (MSC service thread 1-1) WFLYEJB0473: JNDI bindings for session bean named ‘Sum’ in deployment unit ‘deployment “EjbSum.jar”‘ are as follows:

java:global/EjbSum/Sum!SumRemote
java:app/EjbSum/Sum!SumRemote
java:module/Sum!SumRemote
java:jboss/exported/EjbSum/Sum!SumRemote
ejb:/EjbSum/Sum!SumRemote
java:global/EjbSum/Sum
java:app/EjbSum/Sum
java:module/Sum

5. Test

# java StandaloneClient
Getting the Remote
Apr 19, 2020 2:05:10 AM org.wildfly.naming.client.Version <clinit>
INFO: WildFly Naming version 1.0.11.Final-redhat-00001
Apr 19, 2020 2:05:10 AM org.wildfly.security.Version <clinit>
INFO: ELY00001: WildFly Elytron version 1.10.4.Final-redhat-00001
Apr 19, 2020 2:05:10 AM org.xnio.Xnio <clinit>
INFO: XNIO version 3.7.7.Final-redhat-00001
Apr 19, 2020 2:05:10 AM org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.7.7.Final-redhat-00001
Apr 19, 2020 2:05:10 AM org.jboss.threads.Version <clinit>
INFO: JBoss Threads version 2.3.3.Final-redhat-00001
Apr 19, 2020 2:05:10 AM org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version 5.0.16.Final-redhat-00001
Apr 19, 2020 2:05:10 AM org.jboss.ejb.client.EJBClient <clinit>
INFO: JBoss EJB Client version 4.0.27.Final-redhat-00001
Got the remote InterfaceProxy for remote EJB StatelessEJBLocator for “/EjbSum/Sum”, view is interface SumRemote, affinity is None
20

The 20 is the answer.

5. Comparing Remote vs Local

When Same deploying in the same JVM use local and when using another JVM use remote:

@Local ~

Call by Reference, the overhead is minimal, since it is the same JVM so the parameters is the same, so the references are the same. As results, no overhead.

@Remote ~

Call by Value, processing overhead, since are different JVM, the location is remote, the parameters will be value. Remote method invocation: marshed parameters then.
There is a overhead, because of the marsheling. So no references, but a copy of the value.

@Local annotated beans can only be accessed if they are in the same application.

@Remote annotated beans can be accessed across different applications, residing in different jvms or across application servers.

As pointed here

6. JNDI Reference

ejb:<app>/<moduleName>/<distinctName>/<beanName>!<viewClassName>?stateful
<app>EAR name
<moduleName> name of EJB jar
<distinctName> Optional Name
<beanName> Bean’s class
<ViewClassName> fully qualified class name of the remote interface

7. To extract content from jar file:

jar xf jar-file [archived-file(s)]

8. Get the Environment from the context, it will return what is passed:

System.out.println(context.getEnvironment());

Returns:

{java.naming.factory.initial=org.wildfly.naming.client.WildFlyInitialContextFactory, java.naming.provider.url=remote+http://localhost:8080}

8. References:

For JBoss EAP 7.1:

Coding EJB clients for JBoss EAP 7.1

About EJB

https://www.javaworld.com/article/2071724/ejb-fundamentals-and-session-beans.html

About JNDI:

https://www.javaworld.com/article/2076888/jndi-overview–part-1–an-introduction-to-naming-services.html

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s