{"id":214,"date":"2018-07-27T04:47:14","date_gmt":"2018-07-27T04:47:14","guid":{"rendered":"http:\/\/csp12.epgpbooks.inflibnet.ac.in\/?post_type=chapter&#038;p=214"},"modified":"2018-08-02T07:15:46","modified_gmt":"2018-08-02T07:15:46","slug":"rmi","status":"publish","type":"chapter","link":"https:\/\/ebooks.inflibnet.ac.in\/csp12\/chapter\/rmi\/","title":{"rendered":"RMI"},"content":{"raw":"<div>\r\n\r\n<strong>\u00a0 \u00a0 Java RMI<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">Java RMI is a mechanism to allow the invocation of methods that reside on different Java Virtual Machines (JVMs), either on a remote machine or on the same machine with different JVM (which means it resides in different address space). RMI provides Object-Oriented Remote Procedure Call (RPC). The JVMs may reside on different machines or they could be on the same machine. In either case, the method runs in a different address space than the calling process.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">RMI is a core package of the JDK 1.1. It enables software developers to write distributed applications in which the methods of remote objects can be invoked from other JVMs.<\/p>\r\n&nbsp;\r\n\r\n<strong>Remote Method Invocation<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">Java\u2019s RMI is an alternative mechanism to low level sockets. A remote method invocation is a form of Remote Procedure Call (RPC) that is available on other systems. Instead of creating objects on local machines we can create some of the objects on other machines and we can communicate with those objects as it is done normally with local objects.<\/p>\r\n\r\n<\/div>\r\n<strong style=\"text-align: initial;font-size: 1em\">\u00a0 \u00a0 How it differs from others?<\/strong>\r\n<div>\r\n\r\n&nbsp;\r\n\r\nJava RMI is an Object-Oriented remote procedure call mechanism.\r\n\r\nIt differs from CORBA in the following points,\r\n<ul>\r\n \t<li style=\"text-align: justify\">CORBA is a language and machine independent mechanism. RMI was designed for Java running on a JVM.<\/li>\r\n \t<li style=\"text-align: justify\">CORBA includes more features like,<\/li>\r\n \t<li style=\"text-align: justify\">Server application starting, managing persistent state and support for transactions.<\/li>\r\n \t<li style=\"text-align: justify\">But Java RMI does not have an Object Broker.<\/li>\r\n<\/ul>\r\nIt differs from Sun RPC and DCE RPC in the following feature,\r\n<ul>\r\n \t<li>RMI is not language\/machine independent.<\/li>\r\n \t<li>RMI supports the concept of classes with methods within a class.<\/li>\r\n \t<li>RMI also supports polymorphism.<\/li>\r\n<\/ul>\r\n<strong>\u00a0 \u00a0Principal Similarities between CORBA and RMI<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">Both CORBA and RMI are suitable for distributed, Object-oriented, client\/server systems. There is a synchronous interaction via Remote Procedure Call <strong>(RPC)<\/strong>. RPC is implemented via client stubs and server skeletons, which hide networking and data representation. Objects can be both on client and server side.<\/p>\r\n&nbsp;\r\n\r\n<strong>Principal Differences between CORBA and RMI<\/strong>\r\n\r\n&nbsp;\r\n\r\n<strong>CORBA<\/strong>\r\n\r\n&nbsp;\r\n\r\n1. Independent of implementation language.\r\n\r\n2. Operation invocations can be formed statically <em>or<\/em> dynamically.\r\n\r\n3. Object implementation binding can be static or dynamic.\r\n\r\n4. The CORBA object adapters define various object execution semantics.\r\n\r\n<span style=\"font-size: 1em;text-align: initial\">5. Many integrated object services are available.<\/span>\r\n\r\n<\/div>\r\n<div>\r\n\r\n<strong>\u00a0 <\/strong>\r\n\r\n<strong>RMI<\/strong>\r\n\r\n&nbsp;\r\n\r\n1. Requires objects to be programmed in Java.\r\n\r\n2. Objects are platform independent.\r\n\r\n3. Operation invocations are formed statically.\r\n\r\n4. Mapping of names to objects is static.\r\n\r\n5. Many object services are being defined within Enterprise JavaBeans.\r\n\r\n6. Requires mobile code support.\r\n\r\n&nbsp;\r\n\r\n<strong>The Goals of RMI<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">RMI supports seamless remote invocations on objects in different Java virtual machines. It also involves callbacks from servers to clients. RMI integrates the distributed object model into the Java language in a natural way while retaining most of the Java language\u2019s object semantics.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">RMI makes the differences between the distributed object model and the local Java object model apparent. It enables writing reliable distributed applications as simple as possible thereby preserving the safety provided by the Java Sun real time environment.<\/p>\r\n\r\n<\/div>\r\n<strong style=\"text-align: initial;font-size: 1em\">\u00a0 \u00a0 RMI Layers<\/strong>\r\n<div>\r\n<p style=\"text-align: center\"><img class=\"size-full wp-image-215 aligncenter\" src=\"http:\/\/csp12.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-122.png\" alt=\"\" width=\"604\" height=\"348\" \/><\/p>\r\n&nbsp;\r\n\r\n<strong>Stub<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">The stub is an object, that acts as a gateway for the client side. All the outgoing requests are routed through it. It resides at the client side and represents the remote object. When the caller invokes method on the stub object, it does the following tasks:<\/p>\r\n&nbsp;\r\n\r\n1.\u00a0 It initiates a connection with remote Virtual Machine (JVM).\r\n\r\n2.\u00a0 It writes and transmits (marshals) the parameters to the remote Virtual Machine (JVM).\r\n\r\n3.\u00a0 It waits for the result\r\n\r\n4.\u00a0 It reads (unmarshals) the return value or exception, and\r\n\r\n5.\u00a0 It finally returns the value to the caller.\r\n\r\n&nbsp;\r\n\r\n<strong>Skeleton<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">The skeleton is an object, that acts as a gateway for the server side object. All the incoming requests are routed through it. When the skeleton receives the incoming request, it does the following tasks:<\/p>\r\n\r\n<\/div>\r\n<span style=\"text-align: initial;font-size: 1em\">\u00a0 \u00a0 1. It reads the parameter for the remote method.<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">2. It invokes the method on the actual remote object.<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">3. It writes and transmits (marshals) the result to the caller.<\/span>\r\n<div>\r\n\r\n\u00a0 \u00a0 In the Java 2 SDK, a stub protocol was introduced that eliminates the need for skeletons.\r\n\r\n&nbsp;\r\n\r\n<strong>Remote reference layer<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">The remote reference layer is a middle layer between the stub\/skeleton layer and the transport layer. It provides the ability to support varying remote reference or invocation protocols independent of the client stub and server skeleton.<\/p>\r\n&nbsp;\r\n\r\n<strong>Transport layer<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">The Transport layer is the low-layer that ships marshal streams between different address spaces. This layer is responsible for setting up connections to remote address spaces, managing the connections, listening to incoming calls, maintaining a table of remote objects that reside in the same address space, setting up connections for an incoming call and locating the dispatcher for the target of the remote call.<\/p>\r\n&nbsp;\r\n\r\n<strong>Two kinds of classes<\/strong>\r\n\r\n&nbsp;\r\n\r\n<strong>Remote class (Remote object)<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">A remote object is one whose instances can be used remotely. A handle to a remote object identifies where that object is located and how to contact it remotely (via RMI). When used locally, it works like any other object. When it is passed as a parameter, its handle is passed (as with ordinary Java objects).<\/p>\r\n&nbsp;\r\n\r\n<strong>Serializable class (Serializable object)<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">A serializable object is one whose value can be marshalled. It can be passed as a parameter or be a return value to a remote object which means the value of object is copied. It implements java.io.Serializable interface.<\/p>\r\n\r\n<\/div>\r\n<strong style=\"text-align: initial;font-size: 1em\">\u00a0 \u00a0 Conditions for serializability<\/strong>\r\n\r\n&nbsp;\r\n<div>\r\n\r\n\u00a0 \u00a0 If an object is to be serialized\r\n\r\n&nbsp;\r\n\r\n1. The class must be declared as \"public\".\r\n\r\n2. The class must implement \"Serializable\".\r\n\r\n3. The class must have a no-argument constructor.\r\n\r\n4. All fields of the class must be serializable, either primitive types or serializable objects.\r\n\r\n&nbsp;\r\n\r\n<strong>Remote vs. Serializable<\/strong>\r\n\r\n&nbsp;\r\n\r\n<strong>A Remote object lives on another computer (such as the Server)<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">You can send messages to a Remote object and get responses back from the object. All you need to know about the Remote object is its interface. Remote objects do not pose much of a security issue.<\/p>\r\n&nbsp;\r\n\r\n<strong>You can transmit a copy of a Serializable object between computers<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">The receiving object needs to know how the object is implemented. It needs the class as well as the interface. There is a way to transmit the class definition and accepting classes <em>does<\/em> pose a security issue.<\/p>\r\n&nbsp;\r\n\r\n<strong>Understanding requirements for the distributed applications<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">If any application performs the following tasks, it can be called as a distributed application.<\/p>\r\n<p style=\"text-align: justify\">1. The application need to locate the remote method<\/p>\r\n<p style=\"text-align: justify\">2. It need to provide the communication with the remote objects, and<\/p>\r\n<p style=\"text-align: justify\">3. The application need to load the class definitions for the objects.<\/p>\r\n<p style=\"text-align: justify\">The RMI application has all these features, so it is called the distributed application.<\/p>\r\n\r\n<\/div>\r\n<strong style=\"text-align: initial;font-size: 1em\">\u00a0 \u00a0Steps to write the RMI program<\/strong>\r\n\r\n&nbsp;\r\n<div>\r\n\r\n\u00a0 \u00a0 There are 6 steps to write the RMI program.\r\n\r\n&nbsp;\r\n\r\n1. Create the remote interface.\r\n\r\n2. Provide the implementation of the remote interface.\r\n\r\n3. Compile the implementation class and create the stub and skeleton objects using the rmic tool.\r\n\r\n4. Start the registry service by rmiregistry tool.\r\n\r\n5. Create and start the remote application.\r\n\r\n6. Create and start the client application.\r\n\r\n&nbsp;\r\n\r\n<strong>Example<\/strong>\r\n\r\n&nbsp;\r\n\r\n<strong>1) Create the remote interface<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">For creating the remote interface, we need to extend the Remote interface and declare the RemoteException with all the methods of the remote interface.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">Here, we are creating a remote interface that extends the Remote interface. There is only one method named add() and it declares RemoteException.<\/p>\r\n&nbsp;\r\n\r\nimport java.rmi.*;\r\n\r\npublic interface Adder extends Remote\r\n\r\n{\r\n\r\npublic int add( int x, int y ) throws RemoteException;\r\n\r\n}\r\n\r\n&nbsp;\r\n\r\n<strong>2) Provide the implementation of the remote interface<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">Now provide the implementation of the remote interface. For providing the implementation of the Remote interface, it is necessary to either extend the UnicastRemoteObject class, or use the exportObject() method of the UnicastRemoteObject class.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">In case, we extend the UnicastRemoteObject class, we must define a constructor that declares RemoteException.<\/p>\r\n&nbsp;\r\n\r\nimport java.rmi.*;\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">import java.rmi.server.*;<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">public class AdderRemote extends UnicastRemoteObject implements Adder<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">{<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">AdderRemote() throws RemoteException<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">{<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">super();<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">}<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">public int add(int x,int y)<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">{<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">return x+y;<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">}<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">}<\/span>\r\n\r\n<\/div>\r\n<div>\r\n\r\n<strong>\u00a0 \u00a0<\/strong>\r\n\r\n<strong>3) Create the stub and skeleton objects using the rmic tool<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">Next step is to create the stub and skeleton objects using the rmi compiler. The rmic tool invokes the RMI compiler and creates the stub and skeleton objects.<\/p>\r\n<p style=\"text-align: justify\">rmic AdderRemote<\/p>\r\n&nbsp;\r\n\r\n<strong>4) Start the registry service by the rmiregistry tool<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">Now start the registry service by using the rmiregistry tool. If you don't specify the port number, it uses a default port number.In this example, we are using the port number 5000.<\/p>\r\nrmiregistry 5000\r\n\r\n&nbsp;\r\n\r\n<strong>5) Create and run the server application<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">Now rmi services needs to be hosted in a server process. The Naming class provides methods to get and store the remote object.<\/p>\r\n<p style=\"text-align: justify\">In this example, we are binding the remote object by the name Add.<\/p>\r\nimport java.rmi.*;\r\n\r\nimport java.rmi.registry.*;\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">public class MyServer<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">{<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">public static void main(String args[])<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">{<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">try<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">{<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">Adder stub=new AdderRemote();<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">Naming.rebind(\"rmi:\/\/localhost:5000\/Add\", stub);<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">}<\/span><span style=\"text-align: initial;font-size: 1em\">catch(Exception e)<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">{<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">System.out.println(e);<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">}<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">}<\/span>\r\n\r\n<span style=\"text-align: initial;font-size: 1em\">}<\/span>\r\n\r\n<\/div>\r\n<div>\r\n\r\n<strong>\u00a0 \u00a0<\/strong>\r\n\r\n<strong>6) Create and run the client application<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">At the client we are getting the stub object by the lookup() method of the Naming class and invoking the method on this object.<\/p>\r\n<p style=\"text-align: justify\">In this example, we are running the server and client applications, in the same machine so we are using localhost.<\/p>\r\n&nbsp;\r\n\r\nimport java.rmi.*;\r\n\r\npublic class MyClient{\r\n\r\npublic static void main(String args[]){\r\n\r\ntry{\r\n\r\nAdder stub=(Adder)Naming.lookup(\"rmi:\/\/localhost:5000\/Add\");\r\n\r\nSystem.out.println(stub.add(34,4));\r\n\r\n}catch(Exception e){}\r\n\r\n}\r\n\r\n}\r\n\r\n&nbsp;\r\n\r\n<strong>Output<\/strong>\r\n\r\n&nbsp;\r\n\r\nFigure 24.1 shows the screen shot of invoking the RMI compiler and starting the RMI registry at port no 5000.\r\n\r\n<\/div>\r\n<p style=\"text-align: center\"><strong><img class=\"size-full wp-image-216 aligncenter\" src=\"http:\/\/csp12.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-123.png\" alt=\"\" width=\"622\" height=\"217\" \/><\/strong><\/p>\r\n\r\n<div>\r\n<p style=\"text-align: center\"><strong>Figure 24.1 Invoking RMI Registry<\/strong><\/p>\r\n&nbsp;\r\n\r\n<strong>\u00a024.1 Invoking RMI Registry<\/strong>\r\n\r\n&nbsp;\r\n\r\nFigure 24.2 shows the screen shot of running the server application.\r\n\r\n&nbsp;\r\n<p style=\"text-align: center\"><img class=\"size-full wp-image-217 aligncenter\" src=\"http:\/\/csp12.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-124.png\" alt=\"\" width=\"622\" height=\"180\" \/><\/p>\r\n&nbsp;\r\n<p style=\"text-align: center\"><strong>Figure 24.2 Running Server Application<\/strong><\/p>\r\n&nbsp;\r\n\r\nFigure 24.3 shows the screen shot of executing the client application.\r\n\r\n<\/div>\r\n<div>\r\n<p style=\"text-align: center\"><img class=\"size-full wp-image-218 aligncenter\" src=\"http:\/\/csp12.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-125.png\" alt=\"\" width=\"628\" height=\"211\" \/><\/p>\r\n&nbsp;\r\n<p style=\"text-align: center\"><strong>Figure 24.3 Executing Client Application<\/strong><\/p>\r\n&nbsp;\r\n\r\n&nbsp;\r\n\r\n<strong>Distributed Garbage Collection<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">When stand-alone applications are developed using Java, objects that are no longer referenced by any client are automatically deleted. This is a desirable feature when developing distributed applications. The RMI system provides a distributed garbage collector that automatically deletes remote objects that are no longer referenced by any client.<\/p>\r\n&nbsp;\r\n\r\n<strong>Security<\/strong>\r\n<ul>\r\n \t<li style=\"text-align: justify\">There is no authentication; a client just requests through the object (stub), and the server supplies it. Subsequent communication is assumed to be from the same client.<\/li>\r\n \t<li style=\"text-align: justify\">There is no access control to the objects.<\/li>\r\n \t<li style=\"text-align: justify\">There are no security checks on the RMI registry itself, any caller is allowed to make request.<\/li>\r\n \t<li style=\"text-align: justify\">There is no version control between the stubs and the skeletons, making it possible for client to use a down-level stub to access a more recent skeleton breaking release-to-release binary compatibility.<\/li>\r\n<\/ul>\r\n<strong>\u00a0 \u00a0 Summary<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">This module explains about RMI, allowing one Java Virtual Machine to invoke methods of another, and to share any Java object type, even if client or server has never come across that object type before. It\u00a0<span style=\"text-align: initial;font-size: 1em\">gave a broad view of how RMI differs from other APIs and it explored the RMI layers. It also discussed about the steps to write an RMI program with an example.<\/span><\/p>\r\n\r\n<\/div>\r\n<strong>\u00a0 \u00a0References<\/strong>\r\n<ul>\r\n \t<li><a href=\"http:\/\/www.javatpoint.com\/rmi\">http:\/\/www.javatpoint.com\/rmi<\/a><\/li>\r\n \t<li><a href=\"http:\/\/www.javaworld.com\/(magazine)\">http:\/\/www.javaworld.com\/(magazine)<\/a><\/li>\r\n \t<li style=\"text-align: justify\"><a href=\"https:\/\/s3-us-west-2.amazonaws.com\/dsuntestuff\/java\/Remote+Method+Invocation+%28RMI%29.pdf\">https:\/\/s3-us-west-<\/a><a style=\"text-align: initial;font-size: 1em\" href=\"https:\/\/s3-us-west-2.amazonaws.com\/dsuntestuff\/java\/Remote+Method+Invocation+%28RMI%29.pdf\">2.amazonaws.com\/dsuntestuff\/java\/Remote+Method+Invocation+%28RMI%29.pdf<\/a><\/li>\r\n<\/ul>","rendered":"<div>\n<p><strong>\u00a0 \u00a0 Java RMI<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">Java RMI is a mechanism to allow the invocation of methods that reside on different Java Virtual Machines (JVMs), either on a remote machine or on the same machine with different JVM (which means it resides in different address space). RMI provides Object-Oriented Remote Procedure Call (RPC). The JVMs may reside on different machines or they could be on the same machine. In either case, the method runs in a different address space than the calling process.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">RMI is a core package of the JDK 1.1. It enables software developers to write distributed applications in which the methods of remote objects can be invoked from other JVMs.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Remote Method Invocation<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">Java\u2019s RMI is an alternative mechanism to low level sockets. A remote method invocation is a form of Remote Procedure Call (RPC) that is available on other systems. Instead of creating objects on local machines we can create some of the objects on other machines and we can communicate with those objects as it is done normally with local objects.<\/p>\n<\/div>\n<p><strong style=\"text-align: initial;font-size: 1em\">\u00a0 \u00a0 How it differs from others?<\/strong><\/p>\n<div>\n<p>&nbsp;<\/p>\n<p>Java RMI is an Object-Oriented remote procedure call mechanism.<\/p>\n<p>It differs from CORBA in the following points,<\/p>\n<ul>\n<li style=\"text-align: justify\">CORBA is a language and machine independent mechanism. RMI was designed for Java running on a JVM.<\/li>\n<li style=\"text-align: justify\">CORBA includes more features like,<\/li>\n<li style=\"text-align: justify\">Server application starting, managing persistent state and support for transactions.<\/li>\n<li style=\"text-align: justify\">But Java RMI does not have an Object Broker.<\/li>\n<\/ul>\n<p>It differs from Sun RPC and DCE RPC in the following feature,<\/p>\n<ul>\n<li>RMI is not language\/machine independent.<\/li>\n<li>RMI supports the concept of classes with methods within a class.<\/li>\n<li>RMI also supports polymorphism.<\/li>\n<\/ul>\n<p><strong>\u00a0 \u00a0Principal Similarities between CORBA and RMI<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">Both CORBA and RMI are suitable for distributed, Object-oriented, client\/server systems. There is a synchronous interaction via Remote Procedure Call <strong>(RPC)<\/strong>. RPC is implemented via client stubs and server skeletons, which hide networking and data representation. Objects can be both on client and server side.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Principal Differences between CORBA and RMI<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p><strong>CORBA<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>1. Independent of implementation language.<\/p>\n<p>2. Operation invocations can be formed statically <em>or<\/em> dynamically.<\/p>\n<p>3. Object implementation binding can be static or dynamic.<\/p>\n<p>4. The CORBA object adapters define various object execution semantics.<\/p>\n<p><span style=\"font-size: 1em;text-align: initial\">5. Many integrated object services are available.<\/span><\/p>\n<\/div>\n<div>\n<p><strong>\u00a0 <\/strong><\/p>\n<p><strong>RMI<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>1. Requires objects to be programmed in Java.<\/p>\n<p>2. Objects are platform independent.<\/p>\n<p>3. Operation invocations are formed statically.<\/p>\n<p>4. Mapping of names to objects is static.<\/p>\n<p>5. Many object services are being defined within Enterprise JavaBeans.<\/p>\n<p>6. Requires mobile code support.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>The Goals of RMI<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">RMI supports seamless remote invocations on objects in different Java virtual machines. It also involves callbacks from servers to clients. RMI integrates the distributed object model into the Java language in a natural way while retaining most of the Java language\u2019s object semantics.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">RMI makes the differences between the distributed object model and the local Java object model apparent. It enables writing reliable distributed applications as simple as possible thereby preserving the safety provided by the Java Sun real time environment.<\/p>\n<\/div>\n<p><strong style=\"text-align: initial;font-size: 1em\">\u00a0 \u00a0 RMI Layers<\/strong><\/p>\n<div>\n<p style=\"text-align: center\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-215 aligncenter\" src=\"http:\/\/csp12.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-122.png\" alt=\"\" width=\"604\" height=\"348\" srcset=\"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-122.png 604w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-122-300x173.png 300w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-122-65x37.png 65w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-122-225x130.png 225w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-122-350x202.png 350w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Stub<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">The stub is an object, that acts as a gateway for the client side. All the outgoing requests are routed through it. It resides at the client side and represents the remote object. When the caller invokes method on the stub object, it does the following tasks:<\/p>\n<p>&nbsp;<\/p>\n<p>1.\u00a0 It initiates a connection with remote Virtual Machine (JVM).<\/p>\n<p>2.\u00a0 It writes and transmits (marshals) the parameters to the remote Virtual Machine (JVM).<\/p>\n<p>3.\u00a0 It waits for the result<\/p>\n<p>4.\u00a0 It reads (unmarshals) the return value or exception, and<\/p>\n<p>5.\u00a0 It finally returns the value to the caller.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Skeleton<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">The skeleton is an object, that acts as a gateway for the server side object. All the incoming requests are routed through it. When the skeleton receives the incoming request, it does the following tasks:<\/p>\n<\/div>\n<p><span style=\"text-align: initial;font-size: 1em\">\u00a0 \u00a0 1. It reads the parameter for the remote method.<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">2. It invokes the method on the actual remote object.<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">3. It writes and transmits (marshals) the result to the caller.<\/span><\/p>\n<div>\n<p>\u00a0 \u00a0 In the Java 2 SDK, a stub protocol was introduced that eliminates the need for skeletons.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Remote reference layer<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">The remote reference layer is a middle layer between the stub\/skeleton layer and the transport layer. It provides the ability to support varying remote reference or invocation protocols independent of the client stub and server skeleton.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Transport layer<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">The Transport layer is the low-layer that ships marshal streams between different address spaces. This layer is responsible for setting up connections to remote address spaces, managing the connections, listening to incoming calls, maintaining a table of remote objects that reside in the same address space, setting up connections for an incoming call and locating the dispatcher for the target of the remote call.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Two kinds of classes<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Remote class (Remote object)<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">A remote object is one whose instances can be used remotely. A handle to a remote object identifies where that object is located and how to contact it remotely (via RMI). When used locally, it works like any other object. When it is passed as a parameter, its handle is passed (as with ordinary Java objects).<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Serializable class (Serializable object)<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">A serializable object is one whose value can be marshalled. It can be passed as a parameter or be a return value to a remote object which means the value of object is copied. It implements java.io.Serializable interface.<\/p>\n<\/div>\n<p><strong style=\"text-align: initial;font-size: 1em\">\u00a0 \u00a0 Conditions for serializability<\/strong><\/p>\n<p>&nbsp;<\/p>\n<div>\n<p>\u00a0 \u00a0 If an object is to be serialized<\/p>\n<p>&nbsp;<\/p>\n<p>1. The class must be declared as &#8220;public&#8221;.<\/p>\n<p>2. The class must implement &#8220;Serializable&#8221;.<\/p>\n<p>3. The class must have a no-argument constructor.<\/p>\n<p>4. All fields of the class must be serializable, either primitive types or serializable objects.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Remote vs. Serializable<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p><strong>A Remote object lives on another computer (such as the Server)<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">You can send messages to a Remote object and get responses back from the object. All you need to know about the Remote object is its interface. Remote objects do not pose much of a security issue.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>You can transmit a copy of a Serializable object between computers<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">The receiving object needs to know how the object is implemented. It needs the class as well as the interface. There is a way to transmit the class definition and accepting classes <em>does<\/em> pose a security issue.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Understanding requirements for the distributed applications<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">If any application performs the following tasks, it can be called as a distributed application.<\/p>\n<p style=\"text-align: justify\">1. The application need to locate the remote method<\/p>\n<p style=\"text-align: justify\">2. It need to provide the communication with the remote objects, and<\/p>\n<p style=\"text-align: justify\">3. The application need to load the class definitions for the objects.<\/p>\n<p style=\"text-align: justify\">The RMI application has all these features, so it is called the distributed application.<\/p>\n<\/div>\n<p><strong style=\"text-align: initial;font-size: 1em\">\u00a0 \u00a0Steps to write the RMI program<\/strong><\/p>\n<p>&nbsp;<\/p>\n<div>\n<p>\u00a0 \u00a0 There are 6 steps to write the RMI program.<\/p>\n<p>&nbsp;<\/p>\n<p>1. Create the remote interface.<\/p>\n<p>2. Provide the implementation of the remote interface.<\/p>\n<p>3. Compile the implementation class and create the stub and skeleton objects using the rmic tool.<\/p>\n<p>4. Start the registry service by rmiregistry tool.<\/p>\n<p>5. Create and start the remote application.<\/p>\n<p>6. Create and start the client application.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Example<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p><strong>1) Create the remote interface<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">For creating the remote interface, we need to extend the Remote interface and declare the RemoteException with all the methods of the remote interface.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">Here, we are creating a remote interface that extends the Remote interface. There is only one method named add() and it declares RemoteException.<\/p>\n<p>&nbsp;<\/p>\n<p>import java.rmi.*;<\/p>\n<p>public interface Adder extends Remote<\/p>\n<p>{<\/p>\n<p>public int add( int x, int y ) throws RemoteException;<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p><strong>2) Provide the implementation of the remote interface<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">Now provide the implementation of the remote interface. For providing the implementation of the Remote interface, it is necessary to either extend the UnicastRemoteObject class, or use the exportObject() method of the UnicastRemoteObject class.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">In case, we extend the UnicastRemoteObject class, we must define a constructor that declares RemoteException.<\/p>\n<p>&nbsp;<\/p>\n<p>import java.rmi.*;<\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">import java.rmi.server.*;<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">public class AdderRemote extends UnicastRemoteObject implements Adder<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">{<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">AdderRemote() throws RemoteException<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">{<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">super();<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">}<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">public int add(int x,int y)<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">{<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">return x+y;<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">}<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">}<\/span><\/p>\n<\/div>\n<div>\n<p><strong>\u00a0 \u00a0<\/strong><\/p>\n<p><strong>3) Create the stub and skeleton objects using the rmic tool<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">Next step is to create the stub and skeleton objects using the rmi compiler. The rmic tool invokes the RMI compiler and creates the stub and skeleton objects.<\/p>\n<p style=\"text-align: justify\">rmic AdderRemote<\/p>\n<p>&nbsp;<\/p>\n<p><strong>4) Start the registry service by the rmiregistry tool<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">Now start the registry service by using the rmiregistry tool. If you don&#8217;t specify the port number, it uses a default port number.In this example, we are using the port number 5000.<\/p>\n<p>rmiregistry 5000<\/p>\n<p>&nbsp;<\/p>\n<p><strong>5) Create and run the server application<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">Now rmi services needs to be hosted in a server process. The Naming class provides methods to get and store the remote object.<\/p>\n<p style=\"text-align: justify\">In this example, we are binding the remote object by the name Add.<\/p>\n<p>import java.rmi.*;<\/p>\n<p>import java.rmi.registry.*;<\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">public class MyServer<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">{<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">public static void main(String args[])<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">{<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">try<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">{<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">Adder stub=new AdderRemote();<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">Naming.rebind(&#8220;rmi:\/\/localhost:5000\/Add&#8221;, stub);<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">}<\/span><span style=\"text-align: initial;font-size: 1em\">catch(Exception e)<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">{<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">System.out.println(e);<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">}<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">}<\/span><\/p>\n<p><span style=\"text-align: initial;font-size: 1em\">}<\/span><\/p>\n<\/div>\n<div>\n<p><strong>\u00a0 \u00a0<\/strong><\/p>\n<p><strong>6) Create and run the client application<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">At the client we are getting the stub object by the lookup() method of the Naming class and invoking the method on this object.<\/p>\n<p style=\"text-align: justify\">In this example, we are running the server and client applications, in the same machine so we are using localhost.<\/p>\n<p>&nbsp;<\/p>\n<p>import java.rmi.*;<\/p>\n<p>public class MyClient{<\/p>\n<p>public static void main(String args[]){<\/p>\n<p>try{<\/p>\n<p>Adder stub=(Adder)Naming.lookup(&#8220;rmi:\/\/localhost:5000\/Add&#8221;);<\/p>\n<p>System.out.println(stub.add(34,4));<\/p>\n<p>}catch(Exception e){}<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Output<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>Figure 24.1 shows the screen shot of invoking the RMI compiler and starting the RMI registry at port no 5000.<\/p>\n<\/div>\n<p style=\"text-align: center\"><strong><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-216 aligncenter\" src=\"http:\/\/csp12.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-123.png\" alt=\"\" width=\"622\" height=\"217\" srcset=\"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-123.png 622w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-123-300x105.png 300w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-123-65x23.png 65w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-123-225x78.png 225w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-123-350x122.png 350w\" sizes=\"auto, (max-width: 622px) 100vw, 622px\" \/><\/strong><\/p>\n<div>\n<p style=\"text-align: center\"><strong>Figure 24.1 Invoking RMI Registry<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p><strong>\u00a024.1 Invoking RMI Registry<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>Figure 24.2 shows the screen shot of running the server application.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: center\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-217 aligncenter\" src=\"http:\/\/csp12.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-124.png\" alt=\"\" width=\"622\" height=\"180\" srcset=\"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-124.png 622w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-124-300x87.png 300w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-124-65x19.png 65w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-124-225x65.png 225w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-124-350x101.png 350w\" sizes=\"auto, (max-width: 622px) 100vw, 622px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: center\"><strong>Figure 24.2 Running Server Application<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>Figure 24.3 shows the screen shot of executing the client application.<\/p>\n<\/div>\n<div>\n<p style=\"text-align: center\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-218 aligncenter\" src=\"http:\/\/csp12.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-125.png\" alt=\"\" width=\"628\" height=\"211\" srcset=\"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-125.png 628w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-125-300x101.png 300w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-125-65x22.png 65w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-125-225x76.png 225w, https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-content\/uploads\/sites\/60\/2018\/07\/Untitled-125-350x118.png 350w\" sizes=\"auto, (max-width: 628px) 100vw, 628px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: center\"><strong>Figure 24.3 Executing Client Application<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Distributed Garbage Collection<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">When stand-alone applications are developed using Java, objects that are no longer referenced by any client are automatically deleted. This is a desirable feature when developing distributed applications. The RMI system provides a distributed garbage collector that automatically deletes remote objects that are no longer referenced by any client.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Security<\/strong><\/p>\n<ul>\n<li style=\"text-align: justify\">There is no authentication; a client just requests through the object (stub), and the server supplies it. Subsequent communication is assumed to be from the same client.<\/li>\n<li style=\"text-align: justify\">There is no access control to the objects.<\/li>\n<li style=\"text-align: justify\">There are no security checks on the RMI registry itself, any caller is allowed to make request.<\/li>\n<li style=\"text-align: justify\">There is no version control between the stubs and the skeletons, making it possible for client to use a down-level stub to access a more recent skeleton breaking release-to-release binary compatibility.<\/li>\n<\/ul>\n<p><strong>\u00a0 \u00a0 Summary<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">This module explains about RMI, allowing one Java Virtual Machine to invoke methods of another, and to share any Java object type, even if client or server has never come across that object type before. It\u00a0<span style=\"text-align: initial;font-size: 1em\">gave a broad view of how RMI differs from other APIs and it explored the RMI layers. It also discussed about the steps to write an RMI program with an example.<\/span><\/p>\n<\/div>\n<p><strong>\u00a0 \u00a0References<\/strong><\/p>\n<ul>\n<li><a href=\"http:\/\/www.javatpoint.com\/rmi\">http:\/\/www.javatpoint.com\/rmi<\/a><\/li>\n<li><a href=\"http:\/\/www.javaworld.com\/(magazine)\">http:\/\/www.javaworld.com\/(magazine)<\/a><\/li>\n<li style=\"text-align: justify\"><a href=\"https:\/\/s3-us-west-2.amazonaws.com\/dsuntestuff\/java\/Remote+Method+Invocation+%28RMI%29.pdf\">https:\/\/s3-us-west-<\/a><a style=\"text-align: initial;font-size: 1em\" href=\"https:\/\/s3-us-west-2.amazonaws.com\/dsuntestuff\/java\/Remote+Method+Invocation+%28RMI%29.pdf\">2.amazonaws.com\/dsuntestuff\/java\/Remote+Method+Invocation+%28RMI%29.pdf<\/a><\/li>\n<\/ul>\n","protected":false},"author":4,"menu_order":22,"template":"","meta":{"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":["dr-m-vijayalakshmi"],"pb_section_license":""},"chapter-type":[],"contributor":[58],"license":[],"class_list":["post-214","chapter","type-chapter","status-publish","hentry","contributor-dr-m-vijayalakshmi"],"part":3,"_links":{"self":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-json\/pressbooks\/v2\/chapters\/214","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-json\/pressbooks\/v2\/chapters"}],"about":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-json\/wp\/v2\/types\/chapter"}],"author":[{"embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-json\/wp\/v2\/users\/4"}],"version-history":[{"count":8,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-json\/pressbooks\/v2\/chapters\/214\/revisions"}],"predecessor-version":[{"id":570,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-json\/pressbooks\/v2\/chapters\/214\/revisions\/570"}],"part":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-json\/pressbooks\/v2\/parts\/3"}],"metadata":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-json\/pressbooks\/v2\/chapters\/214\/metadata\/"}],"wp:attachment":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-json\/wp\/v2\/media?parent=214"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-json\/pressbooks\/v2\/chapter-type?post=214"},{"taxonomy":"contributor","embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-json\/wp\/v2\/contributor?post=214"},{"taxonomy":"license","embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp12\/wp-json\/wp\/v2\/license?post=214"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}