Java RMI without RMI Registry - java

I am rather new to java RMI and am trying to create a Peer 2 Peer bit torrent like application wherein multiple instances of the same peer may be on the same machine. This would mean that I would need to be able to have more than one remote object of the same type registered on the same machine. The RMI registry seems to only allow me to have one implementation of a Remote Object on any machine as the registry would not be able to differentiate between which of the objects it should be returning a reference to. Is there a way to bypass the registry such as by specifying an IP and port where I know the other peer is exposing its remote object? If not do you have any ideas how I would be able to create multiple instances of the same object on the same machine? Any help with this would be greatly appreciated...

You can either start multiple rmi registries on different ports, or better bind the instances of the object under different names multiple times. But the best way is probably to do the logic in your code and return a new remote object every time it is needed. E.g. dependent on a parameter:
public MyRemoteObject connect(String name) throws java.rmi.RemoteException {
if("first".equals(name)){
return firstinstance;
}else if("new".equals(name)){
return new MyRemoteObject();
}
...
}
or something like this...

I would suggest you to forget about RMI - IMHO this technique is not applicable for your use case.
Define yourself a network protocol including a serialization and deserialization logic and use this for sending and receiving data on a raw socket connection.

Related

How to send a "command" Object through Sockets to be excecuted on the server? Java

i am working on a chat program.
[JAVA] [Without RMI, just Sockets] [Command example: 'sentToMike', 'Disconnect', 'Login', etc]
How do i send a "command" Object through Sockets to be excecuted on the server directly?
I want to send all kind of messages(Strings, Audio, Video), and all kind of Command objects to many clients, any of them. I know there exist ObjectInput/Output objects and all of that. My problem is trying to get a polymorphic solution.
For example i want to create a IMessage interface with a method signature "execute()". Then i would create a AudioMessage, TextMessage, etc that implements the IMessage. The problem is that at some point i need to share the server code with the client and viceversa in order Server and client know all the objects involved in every excecute method. And worst of all is that if i send an IMessage, the server would't know what specific type the message is, so i dont know to what kind cast the Object. The same would happen when i send the Command back to the client.
I can work a solution with simple text strings "commands" and a big and ugly switch in the server(and in the client by the way), but i believe that is not elegant, i would need to create a wrapper class with the string command plus the object of the kind i want to send plus the string with the type of object been sent(Message[String type; String command; IMessage->AudioMessage ]), this wont be polymorphic since i will need to use the switch to ask the type of the object and then cast it to AudioMessage for example. Furthermore i would need to share a lot of code between server and client and i dont know if that would be ok.
Any advice will be very very welcome, maybe i need a design pattern, an architecture pattern, i have no clue.
There are security reason to not allow just any code to run on server!
But if you are willing to expose your server (and client) to unknown code, then you need to also serve classes bytecode, and have classloaders to enable instanciating classes' types you expect the other end to accept. Your protocol would have to send the full classname and locations (if not inlining the bytecode) of the alien class (and all its dependencies not found in parent classloader), for the purpose of hoping to call any method of such object.
(FYI, that just reinventing RMI).
If you don't have to call anything on this object (it's not your case, I know, but I musy say it), then it is passive and there is really no point in transporting it as an object instance.

Reuse Provide in Guice based on parameters

I've tried searching for this but haven't really found a solution so decided to post a question.
I'm working on an application where a user will input an IP (an SNMP device) and my application needs to connect to it and work with it. During runtime of the application, the user may provide another IP address and then I need to connect to the second one also keeping both the connections alive (as singletons).
My problem is I'm not able to wrap my head around this conceptually. My connection module is right now something like the following:
#Override
Configure() {
String ip = first ip;
}
#Provides
Connect connect() {
// connect to ip
return connection;
}
Can anyone give me some hints here?
You should probably pass the IP address as an argument for your Connect class constructor. You can then look at FactoryModuleBuilder so that you can inject dependencies to your Connect class in your code. As for your requirement about singletons, I am not too sure of what you mean there. A singleton means, by definition, that there's only one instance of a class. Here, you want two (or possibly more). What I suspect is that you want at most a single Connect instance per IP String in the entire application. If that is the case, your factory needs to be a bit cleverer that the one created automatically by FactoryModuleBuilder. It could be a singleton itself and store an index (map? concurrent map? cache? It depends on your thread-safety requirements) of ip -> connect instances for those that have been already created.
Hope it helps.

How to use simultaneously 2 lan adapters?

I have following task, would you suggest, whether (and how if yes) it is possible to solve it:
A computer has 2 LAN adapters; each one is connected to different network provider.
Some information must be sent via first one and some information via second one.
Is it possible somehow to specify which adapter to use by initialization of a connection?
In Java you can use the NetworkInterface class, in conjunction with Socket.bind() to specify what interface to bind to.
Example, taken from this reference:
NetworkInterface nif = NetworkInterface.getByName("bge0");
Enumeration nifAddresses = nif.getInetAddresses();
Socket soc = new java.net.Socket();
soc.bind(nifAddresses.nextElement());
soc.connect(new InetSocketAddress(address, port));
Then by setting up two sockets, one per interface you can use both simultaneously.
The other way to solve this problem though is with interface bonding, which is a configuration issue (e.g. on Linux) and presents two physical interfaces as one virtual interface. (Bonding is the exact opposite of specifying which interface to use when creating a socket, but isn't a programming issue though)

How to share object between java applications?

I have 2 separate Java Applications running at a time. (Two separate javaw.exe) I need to share an object between them while they are running.
What is the simplest way to achieve this without having any permanent storage?
Objects and their instance variables can be shared between threads in a Java program, which is pretty simple task.
If you require to share objects (instance of it) between two programs, with out data storage, next choise would be using RMI Socket Communication or Java messaging service.
You can use TCP
Use a local software port, say
localhost:999.
Make one application as server (listening on this port) and other as client (will connect to server at localhost:999, but will use different port for it's own use).
Client will serialize your object to stream.
Server does de-serialize!
Example: http://www.java-samples.com/showtutorial.php?tutorialid=1167
I think that Hazelcast works fine for this type of situation. It practically requires no setup (more than that you need to add the dependencies to the Hazelcast jars). The following code sample shows how to setup a shared Map.
// Code in process 1
Config cfg = new Config();
HazelcastInstance instance = Hazelcast.newHazelcastInstance(cfg);
Map<Integer, String> sharedData = instance.getMap("shared");
sharedData.put(1, "This is shared data");
// Code in process 2
Config cfg = new Config();
HazelcastInstance instance = Hazelcast.newHazelcastInstance(cfg);
Map<Integer, String> sharedData = instance.getMap("shared");
String theSharedString = sharedData.get(1);
Hazelcast support various shared data structures including Map, Queue, List, AtomicLong, IdGenerator etc. The documentation is good and in my experience the implementation is solid.
You must decide if you prefer shared and updated state, or simply send an one-time-message-object.
In the first case you would have to share a "remote reference" to some object. RMI is a good approach.
In the second case you only need to serialize the object you want to share and send it. You can send it serialized (converted to byes) over a socket as Ankit said or even you can use:
RMI :) The sender connects to a RMI registered receiver, invokes a method with the mesasge object as a param and forgets about the RMI object
Java Messaging Service (JMS), maybe an overkill...
some other creative but simple thing...
If you can't store the object permanently, you need to transfer it somehow. This can be done either via network or some sort of shared memory.
For first (network) approach, use serialization (java.io.Serializable) and transfer the object over socket. This will require writing socket listeners.
Second approach will require using and configuring a third party library (e.g. EHCache).
Perhaps Oracle Coherence? That works like an in memory map shared across applications.

Is it a good idea to create a class for object identified by names?

I have a list of services which can be identified by names. Every service has a set of parameters (IP address, port, availability and so on). There are also method which can be applied to the services (close connection, open connection, send a message to the server, check if it is responding and so on).
So, I thought it is a natural approach to create a Server class and represent real servers as objects of this class.
But than I realized that it is not really convenient. For example I have a name of the server (just a string) and I would like to do something with this server. Then I need to have a map which maps name of the server to the object representing this server? It does not seems to be an elegant solution.
What I decided is to have a class containing a set of static methods. And then, for example to use it in the following way: ServerClass.sendMessage("NameOfServer","MyMessage") or for example ServerClass.close("NameOfServer") or ServerClass.getIP("NameOfServer").
Is it a good solution?
An advantage of having a class with various instances is that it provides a kind of type safety. If you have
Server myServer = ServerRepository.getServer("NameOfServer");
if (myServer != null) myServer.sendMessage("MyMessage");
then you know before you send the message if your server name has a typo in it (because your repository can't return a matching message).
Do all of your servers expose the same services, or are there some that are dependent on the server. As an example if you have both FooServers which have a method doFoo() and BarServers with a method doBar() but Foo has no doBar and Bar has no doFoo, then this is likely a bad idea as your ServerClass will potentially expose methods that are meaningless to potential callers. If however you know all of your servers are going to be FooServers than this may be a valid approach as you can centralize common code. I would say be careful that your code remains maintainable and you are not forcing common behavior where it needs to be customized, or you end up adding a multitude of extra arguments to indicate "special cases" where you need to the behavior to vary slightly for one reason or another.

Categories