How to invoke EJB from a remote server to another server .. using WILDFLY 10 and JSP?

2

Currently I develop a web application in JSP with WILDFLY 10. Currently my application is divided into modules but I deploy it with the same EAR.

My idea is to divide the application into several modules, an EAR that is a remote ejb which handles all the data-based queries and others and on the other hand several separate wars that remotely call that EJB, all this in order to have a change only deploy the component I need and not the whole application in general since I currently have everything in the same EAR since it is the only way my wars can call the EJB .

The WIldlfy documentation explains how to do it but it is not a very clear documentation.

EJB invocations from a remote server instance

I would like someone to explain to me step by step how to do it and if possible in a windows machine.

    
asked by Leonardo Solano 14.06.2016 в 15:49
source

1 answer

2

Java EE 7

When you deploy an EJB to the application server, it makes a record of them via JNDI - called a binding - with the following data:

java:global/[<application-name>]/<module-name>/<bean-name>!<fully-qualified-bean-interface-name>

Where:

  • application-name: is the name of the application. Only necessary if an EAR has been deployed . It is deduced by:
    • the name of the EAR
    • the value of <display></display> of file application.xml within META-INF .
  • module-name: is the name of the module to which the bean belongs (.jar, .war files) without the extension. This can be overwritten in ejb-jar.xml .
  • bean-name: indicates the simple name of the bean.
  • fully-qualified-bean-interface-name: indicates the qualified name (with everything and package) of the bean or of the interface (in case it is a remote EJB).

This structure was imposed from the EJB 3.1 specification and you can use it in Java EE 7+. Prior to this, each vendor had its own JNDI structure, not allowing fully portable applications.

There are also two more types of JNDI:

  • java:module/ejbName!fullEjbInterfaceName : used when the remote EJB is in the same module.
  • java:app/moduleName/ejbName!fullEjbInterfaceName : used when the remote EJB is in another module but in the same application.

Creating remote EJBs without status

To create a remote EJB it is enough to create an interface and a class that implements it and that, in addition, referenced to the interface by means of the annotation @Remote .

public class CalculadoraRemote {
    public int sumar(int n1, int n2);
    public int restar(int n1, int n2);
    public int multiplicar(int n1, int n2);
    public double dividir(int n1, int n2);
}

@Remote(CalculadoraRemote.class);
public class CalcuadoraBean implements CalculadoraRemote {

    // métodos
}

When we deploy this, the JNDI will be:

java:global/Calculadora/calculadoraejbs/CalculadoraBean!pe.mitsugami.ejb.CalculadoraRemote

Doing lookup of remote EJBs

To do a lookup of an EJB, we will do it by means of the properties of the JNDI:

  • application-name: Only necessary if an EAR has been deployed .
  • module-name: the same, the name of the jar that contains the / the EJB.
  • bean-name: the same
  • fully-qualified-bean-interface-name: the same

Non-JavaEE Components

final Map<String, String> propiedadesJndi = new HashTable<>();
propiedadesJndi.put(Context.URL_PGK_PREFIXES, "org.jboss.client.naming");
final Context contexto = new InitialContext(propiedadesJndi);

// propiedades JNDI
String appName = ""; // o el nombre del EAR en caso hayas desplegado un EAR
String moduleName = "calcuadoraejbs";
String beanName = CalculadoraBean.class.getSimpleName();
String fullyBeanName = CalculadoraBean.class.getName();

// procedemos con la búsqueda
CalculadoraRemote calculadora = (CalculadoraRemote) contexto.lookup("java:global/"+appName+"/"+beanName+"!"+fullyBeanName);

Java EE components

For Java EE components, we can take advantage of the @EJB annotation to inject the remote EJB dependency.

@EJB
private CalculadoraRemote calculadora;

This will work if you only have one implementation of CalculadoraRemote , if you have more it will not work because you will have a problem of ambiguous dependencies . This is solved by means of the attribute name of Stateless|Stateful|Singleton :

@Stateless(name = "calculadoraCientifica")
@Remote(CalculadoraRemote.class)
public class CalculadoraCientifica implements CalculadoraRemote { }

@Stateless(name = "calculadoraSimple")
@Remote(CalculadoraRemote.class)
public class CalculadoraSimple implements CalculadoraRemote { }

And we inject:

@EJB(name = "calculadoraCientifica")
private CalculadoraRemote calculadora;

You can also inject a remote EJB by specifying the JNDI name explicitly by means of the lookup attribute of the% @EJB .

@EJB(lookup = "java:global/calculadoraejbs/CalculadoraBean!pe.mitsugami.ejb.CalculadoraRemote")
private CalculadoraRemote calculadora;
    
answered by 15.06.2016 в 17:54