Concept of stub and Skeleton in EJB 2.X - java

As per my knowledge, in the EJB 2.x, the client uses the home interface to ask for a reference to the component interface and calls Enterprise java bean’s business method using that reference.
But the concept of stub and skeleton are not clear to me.
Is the reference to the component interface acts as a stub? Then which one act as a skeleton?
Please clarify.

Stub and skeleton are actually RMI concepts, EJB is just reusing them. As such, they are only needed when you are using remote interfaces.
Stub is used by the client to invoke methods on the remote EJB -- it is basically a proxy object that implements the remote interface. It is responsible for serializing the invocation into a byte stream and sending it to the server hosting the EJB.
Skeleton is running on the server side -- it receives the remote calls from the stub over the network, deserializes the invocation and and delegates it to the EJB.
See also: Java RMI : What is the role of the stub-skeleton that are generated by the rmic compiler
Nowadays, stubs and skeletons are typically generated at runtime (or the same function is just handled via reflection), so you do not need to worry about them (see also Do I need RMI stubs to access EJBs from my java client? - this is specific to Glassfish, but the general principles usually apply also to other containers).

Skeletons have been obsolete since 1998. Don't worry about them.

Well stub and skeleton are just there when you are using Remote interfaces.
Stub is an object implementing Remote interface (implemented usually by code generation) and skeleton is implemented inside the container and invokes method on the EJB (inside the container).

Related

Java EJB/Hibernate performance, slower first call

I have an Java application which is using an EJB client to make a calls to the server. Server side EJB's create again calls to the DB. Hibernate is used, but second level cache is disabled. When performance testing DB calls using EJB client, usually the first calls take much longer than the next ones, even though calls are made using different parameters. What things can explain or have effect on the performance in this scenario?
EJB's on the top uses Java's RMI calls. Whenever your client calls the EJB components running in an EJB container, then in the meanwhile some expensive operations are performed.
Lets say, you have a remote interface called HelloRemote and a service bean called HelloBean which implements the HelloRemote interface.
1) First your client needs to look-up for the service object which is registered with the JNDI Registry as :
HelloRemote service=(HelloRemote)context.lookup("HelloBean/remote");
// JBoss specific
Here,
i) Your client makes a call to LDAP Server which contains the JNDI Registry and looks for the remote bean registered with the given name.
ii) If the any bean registry with the given name is found then the container first serializes the registered bean object and sends it to the client where it is again deserialized which is also known as marshaling and unmarshaling.
The above step in itself is somewhat costly and that is why it is recommended that if your application architecture is going to use the same JVM for both the client application and the session beans, then use the local interface ( which can be a no-interface option starting from EJB 3.1) instead of using the remote interface.
iii) With the Business interface stub in hand, you now invoke the business operations on that stub interface. This stub performs the required serialization and delegates the call to the container.
The container now performs the deserialization and invokes the corresponding methods on Business interface object. The same process occurs when the result of this invocation is being returned to the cilent.
As you can see there is a lot of Serialization and De-Serialization happening when a client communicates with the EJB component.
Enabling Second Level cache does improves the performance in Hibernate, but In view the communication b/w an EJB Client and an EJB service object is more expensive w.r.to time.
NOTE : I was looking for someone to respond to this post, as i was also eager to know the reasons, however not finding any responses, I had this post with the whatever understanding i have on these topics

If JNDI can be serialised to the local JVM, why we need RMI to call method?

When I use JNDI to get an object from a remote server, the object can be serialised to the local JVM, this way I am assuming that we can call methods on this object locally without RMI, so why we need RMI?
JNDI is a look-up and directory service. It provides a standardized way to acquire resources by name within some context. Usually it used for acquiring shared resources from an application-server context, but depending on implementation, it can also provide for looking up items in a standardized way that represent remote resources.
RMI is a remote method invocation technology built-in to the Java platform. It allows for calling remote java object methods over a binary protocol. It uses Java's built-in serialization handling to make the remote invocation and parameter passing over the network seem transparent. RMI requires it's own directory/look-up service that or might not be integrated with a given JNDI implementation. (Usually they are not integrated.)
So, with all that in mind, hopefully you can see why your question isn't very clear. You might look-up a remote RMI service via JNDI. You might be able to save (serialize) that remote RMI reference to disk and then reconstruct it to use it again later (although that is probably not a good idea.) But regardless, JNDI and RMI are two different things.
When I use JNDI to get an object from a remote server, the object can be serialised to the local JVM, this way I am assuming that we can call methods on this object locally without RMI, so why we need RMI?
So you can call methods remotely. An object that has been deserialized into your local JVM executes in your JVM. A remote object executes in a remote JVM even though you called it from your local JVM.
I am assuming that we can call methods on this object locally without
RMI
No,It is important to understand that you need two extra objects when you make a remote method invocation. The Stub which runs on the client side and de Skeleton which runs on the server side. These objects performs the necessary low level operations.
When the client invokes a remote method it never call directly the object, instead it uses the Stub object.
Therefore, what you get from JNDI service is the Stub not the remote object.

Java RMI : What is the role of the stub-skeleton that are generated by the rmic compiler

I am currently learning Java RMI (Remote Method Invocation), and I followed the tutorial provided by Oracle on it´s website. I have a particular question however:
What is the use of the stub-skeleton generated by rmic? Do I really need it?
The Stub/Skeleton hides the communication details away from the developer. The Stub is the class that implements the remote interface. It serves as a client-side placeholder for the remote object. The stub communicates with the server-side skeleton.
The skeleton is the stub's counterpart on server-side. Both communicate via the network. The skeleton actually knows the real remote objects delegates the stub's request to it and returns the response to the stub.
You require both as they are the essential building blocks for RMI.

How to easily maintain the RMI interfaces across multiple applications like server and client?

Any one dealing with the RMI would certainly have come across this dilemma of how to easily maintain the interfaces to objects providing remote method invocation service to other client applications. Whenever we decide to have a minor change in the method declaration or adding/deleting methods declared in the interface, we have to manually replicate the change in all the clients that would be using that interface for accessing RMI service from a remote server.
Think about having a downloadable (Serializable) agent that has a more stable interface used by the client, and that uses the remote interface to do its job. You can use the codebase feature to ensure its availability to all clients. The agent needs to contain the stub. You can bind the agent to the Registry, or return it from some other remote method.
Or, use JWS to distribute new versions of the clients.
Or, design your remote interfaces more stably so they don't have to change -:)
One of the good workaround I came up with is to
put all the interfaces provided by the RMI server in a separate
project which will pack itself into a jar file when built.
Then just add that jar file as dependency or in the
classpath of the server application which is meant to provide the
RMI service as well as to any of the client applications that
want to use those interfaces for invoking remote methods.
This will ease the task of maintaining RMI interfaces by updating them at just one place. Extra effort of changing method signature in some interface will be limited to changing the application code which calls that method.

RMI's dynamic proxy stub implementation

I want to understand how the dynamic proxy stub implementation is actually done behind the scene. According to what I read, by the time a remote object is exported if no pre-generated stub class is found, the RMI runtime would generate a dynamic proxy to act as the stub. That stub is then bound to the RMI Registry and later accessible by some RMI client.
The question is: since the stub is actually a dynamically generated proxy, its class definition would not be available on the client side, then how come the client is still able to retrieve the stub from the RMI Registry? Is there some kind of dynamic class-loading happening behind the scene or does RMI use another technique to work-around this?
Java.lang.reflect.Proxy is serializable and it has special support in ObjectOutputStream and ObjectInputStream. Basically just the interfaces implemented and the invocation handler are serialized, and a new dynamic proxy is constructed from that during deserialization.
RMI does use dynamic classloading - the classpath is sent alongwith the call as a 'classpath annotation' from which the client loads the class. You can look at the RMI implementation for more info - it's available as part of the JDK source. Specifically, the classes ObjectOutputStream and RMIClassloader.
Update: RMI does not start an HTTP server - in fact, you would need your custom solution for this. One of them as you mention can be an HTTP server that you run, make the classes available through the server, and pass the codebase with the HTTP server's address/port in your stubs, so that your clients can download them.

Categories