When is the skeleton object created in RMI? - java

In books, I read that when we compile implementation class with rmic, it creates two objects: stub and skeleton. But when I compile server side implementation class it only creates a stub object file. The code is:
import java.rmi.*;
import java.rmi.server.*;
public class ServerImp extends UnicastRemoteObject implements testRmi
{
ServerImp() throws RemoteException
{
}
public void getText(String gt) throws RemoteException
{
System.out.println(gt);
}
}
Can somebody tell me when the skeleton file is created?

Since rmic 1.2 onwards, Java doesn't generate skeleton class any more. New JRMP protocol supported for RMI has got rid of the use of skeleton files.
A skeleton for a remote object is a JRMP protocol server-side entity
that has a method that dispatches calls to the actual remote object
implementation.

Skeletons were replaced by general server-side dispatch code in JDK 1.2 (released 1998). Statically generated stubs were replaced by dynamic proxies in JDK 5 (released 2004). There is no longer need to use rmic to generate stubs for running RMI over JRMP. (Note however that rmic is still necessary for using IIOP.)
I'm astounded by the number of questions on stackoverflow asking about rmic, stubs, and skeletons. People must be looking at very old books and very out-of-date web tutorials. It would be helpful if links were posted to some of these so that the authors can be contacted to update or remove the obsolete information.
Maybe the old stub support should be deprecated. That might help avoid the confusion.
Edit: Oh, I guess maybe I should answer the question too. :-)
Edit2: removed erroneous statement about UnicastRemoteObject constructor.
Statically generated skeletons are no longer necessary. In your code above, your remote object extends UnicastRemoteObject. When your object is constructed, the UnicastRemoteObject constructor is called. This hooks up the object to the RMI internal infrastructure that handles socket listening and remote method dispatch. In other words, it "exports" the object.

Related

GWT different interface implementation for client and server

Assume that we've some interface my.gwt.shared.Facade in shared package of our GWT project (exists both server and client) and two implementation of it: class my.gwt.client.ClientFacadeImpl (exists only client) and class my.gwt.server.ServerFacadeImpl (exists only server).
Is there any way to write a piece of code or annotation that substitute ClientFacadeImpl in client side and ServerFacadeImpl in server side?
Thanks all for the answers and discussion. I've found simple and elegant solution for my needs.
So, I've interface my.gwt.shared.Facade and two classes: class my.gwt.client.ClientFacadeImpl and class my.gwt.server.ServerFacadeImpl.
interface Facade {
Map<Boolean, Facade> FACADES = new HashMap<Boolean, Facade>();
}
Now, we should fill you FACADES interface. This is done like that:
public class MyEntry implements EntryPoint {
static {
Facade.FACADES.put(true, ClientFacadeImpl.INSTANCE); // client side
}
And
#Startup
#Singleton
public class Initializer {
#PostConstruct
private void init() {
Facade.FACADES.put(false, ServerFacadeImpl.INSTANCE); // server side
// other things
}
}
Now, when I need to get appropriate Facade, I just write
Facade facade = Facade.FACADES.get(GWT.isClient());
Also in this case in map is only corresponding to server or client side implementation.
P. S. Goal of this question was to allow handling of some GwtEvents fired on client direclty on server and vice-versa. This solution removed large set of DTO (data transfer objects) and simplified code a lot.
There's no answer to your question other than "it depends". Or rather, of course there are ways of doing what you ask, but would you accept the tradeoffs?
Given that you tagged the question with dependency-injection, let's start with that. If you use a DI tool with GWT, it's likely GIN (Dagger 2 would work, but it's still under development). In that case, just use distinct modules for GIN client-side and Guice server-side that bind() the appropriate implementation.
For a few releases, GWT.create() can be made to work outside a GWT (client) environment (i.e. on the server side). You have to register a ClassInstantiator on the ServerGwtBridge as an alternative to the rebind rules from gwt;xml files. So you could have a <replace-with class="my.gwt.client.ClientFacadeImpl"> rule in your gwt.xml, and a ClassInstantiator returning a ServerFacadeImpl on the server side.
Finally, you can also use a static factory and replace it with a client-side specific version by way of <super-source>.
A last one, but I'm unsure whether it'd work: you could use an if/else using GWT.isClient(), and annotate your ServerFacadeImpl with #GwtIncompatible to tell the GWT compiler that you know it's not client-compatible.

how to create rmi in java [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
hi i have searched the internet for a long time trying to find some thing that talk about how to start rmi registry in windows 7 using cmd so if any one know how to do that pleas let me to know how to do it or if any one can provide us a good link for that... thx in advance
ok thanx for all how answered my question when i asked the question i was not fully understand the RMI system or how it work but know i have good idea i will summarized this for provide all with an idea for the RMI system and if i have any mistake please correct me
so
Remote Interface:
We need an interface that extends from the Remote class and defined the method that we would like to invoke remotely
note:
Remote is a "marker" interface that identifies interfaces whose methods may be invoked from a non-local virtual machine.
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Calendar;
public interface CalendarTask extends Remote {
Calendar getDate() throws RemoteException;
}
The Remote Object:
We need class that create a Remote object's so we crate class object implement the Remote Interface to make the object's that created by this class object remote object's and we link this object's to the RMI System by extends from this class UnicastRemoteObjec so When a class extends from UnicastRemoteObject, it must provide a constructor declaring this constructor calls super(), it activates code in UnicastRemoteObject, which performs the RMI linking and remote object initialization.
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Calendar;
public class CalendarImpl extends UnicastRemoteObject implements CalendarTask {
private int counter = 1;
public CalendarImpl() throws RemoteException {}
public Calendar getDate() throws RemoteException{
System.out.print("Method called on server:");
System.out.println("counter = " + counter++);
return Calendar.getInstance();
}
}
Writing the Server:
3.1 The server's job is to accept requests from a client, perform some service, and then send the results back to the client.
3.2 The server must specify an interface that defines the methods available to clients as a service. we do that above in the first step (Remote Interface)
3.3 The server creates the remote object, registers it under some arbitrary name, then waits for remote requests
3.4 so for register The remote object we use java.rmi.registry.LocateRegistry class allows the RMI registry service (provided as part of the JVM) to be started within the code by calling its createRegistry() method.
3.5 The java.rmi.registry.Registry class provides two methods for binding objects to the registry.
• Naming.bind("ArbitraryName", remoteObj);
throws an Exception if an object is already bound under the "ArbitrayName".
• Naming.rebind ("ArbitraryName", remoteObj);
binds the object under the "ArbitraryName" if it does not exist or overwrites the object that is bound.
3.6 The example on the following acts as a server that creates a CalendarImpl object and makes it available to clients by binding it under a name of "TheCalendar"
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
public class CalendarServer {
public static void main(String args[]) {
System.out.println("Starting server...");
// Start RMI registry service and bind
// object to the registry
try {
LocateRegistry.createRegistry(1099);
Naming.rebind("TheCalendar",
new CalendarImpl());
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
System.out.println("Server ready");
}
}
Writing the Client:
4.1 An RMI client is a program that accesses the services provided by a remote object
4.2 The java.rmi.registry.LocateRegistry class allows the RMI registry service to be located by a client by its getRegistry() method
4.3 The java.rmi.registry.Registry class provides a lookup() method that takes the "ArbitraryName" the remote object was bound to by the server.
Once the client obtains a reference to a remote object, it invokes methods as if the object were local
import java.rmi.registry.*;
import java.util.Calendar;
public class CalendarClient {
public static void main(String args[]) {
Calendar c = null;
CalendarTask remoteObj;
String host = "localhost";
if(args.length == 1)
host = args[0];
try {
Registry r =
LocateRegistry.getRegistry(host, 1099);
Object o = r.lookup("TheCalendar");
remoteObj = (CalendarTask) o;
c = remoteObj.getDate();
} catch (Exception e) {
e.printStackTrace();
}
System.out.printf("%tc", c);
}
}
The code you have written doesn't start a registry. LocateRegistry.getRegistry() doesn't do that. Check the Javadoc. It assumes the Registry is already running. LocateRegistry.getRegistry() just constructs a Registry stub according to the host and port you provide. It doesn't even do any network operations.
To start a Registry from within your JVM, use LocateRegistry.createRegistry(), as its Javadoc states.
EDIT: There's a lot of misinformation in your edit.
Remote is a "marker" interface that identifies interfaces whose methods may be invoked from a non-local virtual machine.
Only if implemented by an exported remote object whose stub has been transmitted to that VM. The remote interface itself doesn't have any such magical property. All methods defined in a remote interface must be declared to throw RemoteException, although the implementations of these methods generally don't need to be so declared (i.e. unless they perform remote operations themselves: the compiler will tell you).
We need class that create a Remote object's so we crate class object implement the Remote Interface to make the object's that created by this class object
Far too much confusion here. We need a class. The class must implement the remote interface. This is not an 'object' yet: it is a piece of code that must be compiled to a .class file. A class doesn't 'make objects'. An application does that, with the new operator.
we link this object's to the RMI System by extends from this class UnicastRemoteObjec so When a class extends from UnicastRemoteObject, it must provide a constructor declaring this constructor calls super(), it activates code in UnicastRemoteObject, which performs the RMI linking and remote object initialization
There is no 'link' step in RMI. There is an 'export' step. It is performed either by extending UnicastRemoteObject or by calling UnicastRemoteObject.exportObject(). If you don't extend UnicastRemoteObject you don't need the constructor you described.
The server's job is to accept requests from a client, perform some service, and then send the results back to the client.
The server's job is to implement the methods in the remote interface. RMI does all the rest for you.
The server creates the remote object, registers it under some arbitrary name, then waits for remote requests
Or else the server is the remote object and it registers itself.
for register The remote object we use java.rmi.registry.LocateRegistry class allows the RMI registry service (provided as part of the JVM) to be started within the code by calling its createRegistry() method.
Or you can use an external Registry via the rmiregistry command. Or you can use an LDAP server via JNDI.
LocateRegistry.createRegistry(1099);
Naming.rebind("TheCalendar",
new CalendarImpl());
This won't work unless you store the result of createRegistry() into a static variable. And having stored it, you may as well use it to do the bind, instead of using the Naming class. If you don't store it into a static variable it will be garbage-collected and so will the remote object.
The java.rmi.registry.LocateRegistry class allows the RMI registry service to be located by a client by its getRegistry() method
Or you can use the Naming class, see below.
The java.rmi.registry.Registry class provides a lookup() method that takes the "ArbitraryName" the remote object was bound to by the server.
So does the Naming class. It takes an rmi: URL which specifies the host and port and bind-name. You can omit the rmi:// part. If you omit the host it defaults to 'localhost', but this is only useful if the client is running in the same host as the server, which isn't itself very useful. If you omit the port it defaults to 1099.

AIDL registerCallback() google docs

google docs have a tutorial on how to make an AIDL service. However, when I tried to do the same, I got an error "The method registerCallback(IRemoteInterface) is undefined for the type IRemoteInterface.
I have not seen this "registerCallback" method in any tutorial that I have been googling and my question is why is this not working/why do other places not use it?
I feel like part of my issue is a fundamental misunderstanding about services and their 'callback' to send information to what it is bound to it.
Thanks!
AIDL:
package com.mine.ben;
import com.mine.servicenexus.RelPoint;
interface IRemoteInterface {
Location getLastLocation();
RelPoint getRelPoint();
int logControlActivity(in String text,in int severity);
int getRunningStatus();
}
Updated question:
I get a syntax error in my AIDL file when i add
void registerCallback(IRemoteServiceCallback);
void unregisterCallback(IRemoteServiceCallback);
I have cleaned my workspace and it builds automatically. Is this a problem with the gen file?
Few lines from my application:
interface IGpsService {
Bundle getNavigationMessage();
void resetStatistics();
void recordingEnable(boolean recordingEnabled, boolean continueLastTrack);
void registerCallback(IGpsChanged cb);
void unregisterCallback(IGpsChanged cb);
boolean isRecordingEnabled();
void setGhost(int trackId);
void startGhost();
void sendUserEvent(int eventId);
}
second file for calback interface itself:
interface IGpsChanged{
oneway void onLocationChanged(out Bundle message);
}
Best of all - usually you do not need those .aidl definitions. This is necessary only when exposing service methods outside of the application.
It's also helpful to understand how it works - forst aidl defines basic service's methods. registerCallback is not a "special" method, it's as oridinary as any other, just enables defining callbacks for two-way communication (in this particular case - to send some position info from sesrvice to binded activity (or other component).
As you mentioned in comment - you do not want to create service, just consume some service from outside of application. In that case you need those external aidl file, not the one written by you. Stubs for consuming service's method will be generated in the /gen directory.
google docs have a tutorial on how to make an AIDL service.
That is not a tutorial. It is just ordinary documentation.
However, when I tried to do the same, I got an error "The method registerCallback(IRemoteInterface) is undefined for the type IRemoteInterface.
That is because you do not have a method named registerCallback() in your AIDL.
I have not seen this "registerCallback" method in any tutorial
It is not in a tutorial. The only occurrences of registerCallback() in the Web page that you linked to are from "some sample code demonstrating calling an AIDL-created service, taken from the Remote Service sample in the ApiDemos project". The ApiDemos project is in your SDK installation, if you elected to download sample code from the SDK Manager.
Code example from AIDL guide that you have referenced is taken from the Remote Service sample in the ApiDemos project.
And registerCallback() in it is implemented by using android.os.RemoteCallbackList<E extends android.os.IInterface> object.
Make an .aidl file like:
package com.example;
oneway interface IRemoteServiceCallback {
/**
* Goes to client.
*/
void valueChanged(int value);
}
Make another .aidl file where you import this interface and use it as a method's parameter like:
package com.example;
import com.example.IRemoteServiceCallback;
interface IRemoteService {
/**
* Goes to service.
*/
void registerCallback(IRemoteServiceCallback cb);
}
Generate code from .aidl on both sides.
Implement IRemoteService.Stub in service and return it in onBind()
Implement IRemoteServiceCallback.Stub in client and pass it in ServiceConnection's onServiceConnected() callback to the received from IRemoteService.Stub.asInterface() instance of IRemoteService.
Now you service can talk back to the client over the passed IRemoteServiceCallback implementation.

Communication between Java programs with non-JDK objects

I'm looking for a communication channel between two java programs running on the same machine. I've found a few options (RMI and XML-RCP) but none of the examples that I found show exchange of objects wich class it's non-primitive and not know on JDK (our own objects).
So, what's the easy technology to use when I want to do this (note that Utils.jar it's on the classpath of Server.jar and Client.jar):
Utils.jar:
class MyClassRequestParams { ... }
class MyClassReturnParams { ... }
Client.jar:
// Server creation
...
// Send request
MyClassRequestParams params = new MyClass...
MyClassReturnParams response = server.send("serverMethodName", params);
Server.jar:
MyClassRequestParams serverMethodName(MyClassRequestParams params)
{
MyClassReturnParams response = new MyC...
// do processing
return response;
}
Just make your transport classes implement the Serializable interface, and everything will be fine with RMI. Note that every object referenced bt the transport object should also be Serializable.
The RMI tutorial uses an example with a custom Task interface implemented by a Pi custom class that is not a "standard" JDK class.
You may also consider Versile Java (I am one of its developers). Follow the link for an example of making remote calls and defining remote interfaces. It implements a platform-independent standard for remote ORB interaction, currently also available for python.

Locator and stub class while migrating client side application from Axis to Axis 2

I’m trying to migrate a client side application from Axis to Axis 2. The application also supports connection through RMI so previously, we abstracted away the connection by using the stub and the locator file. For example, we did something like the following:
AddFunctionLocator locator = new AddFunctionLocator ();
AddFunction api = (AddFunctionSoapBindingStub) locator.getAddFunction()
api.addInt(5, 3);
And this worked because the locator class would return the stub class, which in addition to extending org.apache.axis.client.Stub, also implemented the AddFunction interface class.
However, in Axis 2, using WSDL2Java, I cannot figure out if this arrangement is possible since neither the locator class is generated nor does the Stub class implement the original AddFunction interface class. Does anyone have any advice on either the proper options to use with WSDL2Java or another way that I implement so I can keep this abstraction in our client code?
Thanks,
Richard
Unfortunately axis2 doesn't generate interfaces for client stubs.
It does that for server with -ss and -ssi switches, so you could modify client to use these interfaces, though it is not that straight forward.

Categories

Resources