What is Remote EJB? - java

I want to know what is really local and remote EJB. Is remote an EJB which is the same jar file ? Is remote an EJB which is in another JVM ? What is it anyway?
If I have deployed two different EAR files in the same server domain do I need to lookup for EJBs in each other? Lookup is achieved through annotations ? I mean EJB 3.1.

Remote EJBs are used in a distributed environment. The EJBs may run in one JVM, while their consumers run in another.
Local EJBs are used when you can guarantee that all consumers of the EJB are operating within the same JVM.

Related

Glassfish - share EJB web application between nodes

I've got a glassfish server with a couple of EJB wars deployed on several different nodes. I want one of the applications (deployed on node1) to be 'visible' to all applications deployed on different nodes, so that they would be able to inject some remote beans from it. However, I am allowed to have only ONE instance of this application for the wole server, so deploying it separately on all nodes is not possible.
Is this kind of setup possible in glassfish 3.1?
This is achievable through deployment descriptors:
https://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#cross-appserverremoteref
In your sun-web.xml (or glassfish-web.xml, both will work in this case) define ejb-ref as follows:
<ejb-ref>
<ejb-ref-name>fooejbref</ejb-ref-name>
<jndi-name>corbaname:iiop:node_name:node_IIOP_port#foo.bar.YourEJBRemote</jndi-name>
</ejb-ref>
It's not exactly convenient - you will need to define that for each remote bean you need, and add such a descriptor in every app that needs it. It should however work, and I don't know of any better way.

Create a vendor-neutral EJB3 client

Is it possible to create a client that accesses an EJB3 bean, with the client having no dependence on a vendor JAR or configuration? We currently need to support scenarios where our service is deployed on a WebSphere or JBoss server, and the client is deployed as an application either on a WAS or JBoss, or is running as a standalone app.
I used to be able to do to this with EJB2.x beans, I just needed to create stubs using RMIC.
But with EJB3, If I'm connecting to WebSphere I have to include thinclient JARs, plus I have to pre-generate the stubs using WAS tools. For JBoss I have to use jboss-client.jar.
No, this is not possible. This has been made explicit in section 10 of the EJB 3.2 specification:
This chapter describes the interoperability support for accessing an
enterprise bean through the EJB 2.1 remote client view from clients
distributed over a network, and the distributed interoperability
requirements for invocations on enterprise beans from remote clients
that are Java Platform, Enterprise Edition (Java EE) components.
Distributed Interoperability is not defined for the EJB 3.x remote client view.
Also note section 10.5.5:
System value classes are serializable value classes implementing the
javax.ejb.Handle, javax.ejb.HomeHandle, javax.ejb.EJBMetaData,
java.util.Enumeration,java.util.Collection, and java.util.Iterator
interfaces. These value classes are provided by the EJB container
vendor. They must be provided in the form of a JAR file by the
container hosting the referenced bean. For interoperability scenarios,
if a referencing component would use such system value classes at
runtime, the Deployer must ensure that these system value classes
provided by the container hosting the referenced bean are available to
the referencing component. This may be done, for example, by including
these system value classes in the classpath of the referencing
container, or by deploying the system value classes with the
referencing component’s application by providing them to the
deployment tool.
For WebSphere Application Server, the EJB thinclient contains these system value classes as well as the IBM JNDI implementation that uses CosNaming. In theory, this thinclient is not needed if you don't need the system value classes and your client JVM has its own ORB with an implementation of CosNaming.
Short answer: No, it's not possible, as a client needs three things:
The interface classes.
The client libraries of the server AS (yes, sadly)
A configuration telling the client the server address/jndi lookup path (qa, prod etc.)
If your client is running on the same product (let's say JBoss to JBoss communication), you will not be in need of client libraries and just be able to do a remote lookup. If you have a mix of client/server application servers this will make things complicated, as you will have to run client libraries of one product in another server product.
Speaking of standalone applications running as clients, I'd just build and provide 1 heavy client jar/lib containing not only the interface classes, but also the client libs of both servers. Then providing a small helper class that returns the correct InitialContext created and based either on JBoss or Websphere depending on a flag in the client configuration.
I know this last idea ain't a clean solution, though might even work in a different AS product running as "client".

How do I programmatically start/stop an EJB

Does anyone know if it's possible to start/stop an EJB within my application code? Eg. I have some MDBs that I wish to selectively start/stop while my application is running? Any ideas? Can this maybe be done via JMX?
Cheers!
The EJB spec has no mechanism to start/stop individual EJBs (or even modules) within an application. It is possible to start/stop applications dynamically using JMX via JSR 77.
(I see you're using the jboss tag. I have no expertise in JBoss, so I don't know if it provides extensions that support what you want to do.)
An EJB is not something that can be "started" or "stopped". Sure, it has a life cycle but that is more concerned with creation, activation, passivation and removal of EJB instances, and it's entirely up to the EJB container to manage the life cycle.
In short: you can't manage an EJB's life cycle programmatically.
Each deployed MDB has a management MBean. The MBean class is org.jboss.ejb3.mdb.MdbDelegateWrapper. The JMX ObjectName varies between versions of JBoss 4, and vary depending on how you deployed them. Assuming you deployed an MDB called MyMDB in a jar called myapp.jar which was in an ear called myapp.ear, the name might be:
jboss.j2ee:ear=myapp.ear,jar=myapp.jar,name=MyMDB,service=EJB3
Older version of JBoss 4 also had a system hashcode in there. And if you're not using EJB3, I think the service will still be there only it will be EJB2.
Anyways, once you find the management bean, you can call the stop and start operations. We use this frequently to pause message delivery.

Communication between EJBs deployed in different Application Servers from different vendors

I ‘m trying to create a small EJB 3.1 application in which I want to use two application servers from two different vendors. (JBoss 6.1.0 Final and Glassfish 3.1). This is just to experience the taste of distributed applications and new features of EJB3.1.
This is the problem I’m having…
I have created a simple EJB (kind of a hello world ejb) and deployed it in GlassFish server which is running in the machine A. Let’s call it GlassFishHelloWorldEjb. This one has business remote and local views.
I have created another EJB project in which I have an EJB called JBossHelloWorldEjb. I have deployed it in the Jboss server which is running in the machine B.
Now I want to inject GlassFishHelloWorldEjb to a reference in the JBossHelloWorldEjb so that I can call it within the JBossHelloWorldEjb. Then I have a web app deployed in the Jboss which calls the JBossHelloWorldEjb.
MyWebApp(Jboss, machine B)-----> JBossHelloWorldEjb (Jboss, machine B)----> GlassFishHelloWorldEjb(GlassFish, Machine A)
I tried many ways to inject the GlassFishHelloWorldEjb in to the JBossHelloWorldEjb but failed. Could some please shed some light to achieve this.
Would greatly appreciate if you could show me the way to do this through both INJECTION and Programmatic JNDI look up.
Cheers
Lekamge
one option might be to use Spring RemoteEJB Proxies
OR. import client required jars for remote and write your own wrapper

EJB3 Local and Remote interfaces

I understood that Local interface is designed for clients in the same container's JVM instance and remote interface is designed for clients residing outside the EJB container's JVM. How about the web application client which is not reside (or packaged) in the same .ear but reside on the same Java EE server?
Officially #Local annotated beans can only be accessed if they're in the same application. A .war deployed separately from an .ear (or other .war or other .jar EJB) is a different application, even when deployed to the same application server instance.
There's thus no guarantee that the code in your .war can call #Local EJB beans that are defined in the .ear.
However, in practice in nearly all application servers this just works.
There's a request for the EJB 3.2 spec to officially support local cross-application calls: https://download.oracle.com/otndocs/jcp/ejb-3_2-fr-spec
Local interfaces are to be used in communication within the same application. It doesn't necessarily mean JVM.
The point is: even within the same JVM instance, on the same server, two different applications cannot communicate using local interfaces (which means local and no-interface views).
If you have a web component (WAR) as well as a business component (EJB-JAR) which is in the same application, the most intuitive and straightforward solution is to package them in one EAR or in one WAR (since Java EE 6).
You use the remote interfaces, but you make a lookup using JNDI (that's how i'd do it), this way you find the instance of the EJB in the server and can use it in your web application.
Although you still need a jar with the EJB interfaces in the web application project.
EDIT and I agree with JB Nizet, why would you want the WAR outside the EAR?
Remote interfaces can be called across applications, from everywhere within the application server as well as from outside, even from other hosts.
So assume that you need remote (#Remote) interface. In EJB 3.1 you can use dependency injection.

Categories