Limiting RMI to localhost

H

haimcn

Hi

I'm writing a big application that I divide into 2 processes (server
and interface) with RMI to communicate between them.
I would like to limit the access to the server only from the interface
process and also only from the local machine.
Is there a way to limit RMI to localhost only?

I cannot block all sockets outside the machine since I use them in the
server process.

Thanks!
Haim
 
H

haimcn

Simply block the RMI port with the firewall from non-localhost access.  You'll
have to look the port up, I don't remember which one it is off the top of my
head.  It'll be a different port than the ones you expose "in the server process".

This is an OS-specific operation, but most Windows "personal firewall"
products and any Linuxen have the capability.

Thanks for the answer.
I'm searching for a way to control it from the server process.
It is possible to do it from the firewall but this is not in my hands
and it leaves the administrator with the responsibility to do it.
That way my application has a security hole and the administrator can
workaround it.

Any way to do it from the server process?
 
R

Ronny Schuetz

I'm writing a big application that I divide into 2 processes (server
and interface) with RMI to communicate between them.
I would like to limit the access to the server only from the interface
process and also only from the local machine.
Is there a way to limit RMI to localhost only?

I cannot block all sockets outside the machine since I use them in the
server process.

Can't you setup to RMI server socket to explicitly listen on
localhost:<your port>? This way it shouldn't be accessible from outside.

Ronny
 
T

Tom Anderson

Can't you setup to RMI server socket to explicitly listen on
localhost:<your port>? This way it shouldn't be accessible from outside.

A server socket bound to localhost will be able to receive connections
from outside. Unless you mean that <your port> would also be firewalled?
That should work.

How about using the version of UnicastRemoteObject.exportObject that takes
a pair of socket factories? The important one would be the
RMIServerSocketFactory; you could use that to make a special subclass of
ServerSocket that overrides accept() to check the client's address.
Something like:

public Socket accept() throws IOException {
while (true) {
Socket sock = super.accept() ;
if (sock.getRemoteAddress().equals(sock.getLocalAddress())) {
return sock ;
} else {
// might want to log the attempted connection
try {
sock.close() ;
} catch (IOException e) {
// might want to log this too
}
}
}
}

I'm not absolutely sure that this will always work; if you bind the server
socket to localhost, but open connections to yourself via an explicit
name, the addreses might not match. I don't really know how to deal with
that - what's a good general way of asking if an InetAddress refers to an
interface on the local machine? Perhaps you should just make the rule even
stricter, and say that only connections via the loopback interface will be
accepted; this avoids the problem.

The RMIClientSocketFactory would just open sockets in the normal way. It
wouldn't do the clever stuff that RMI's default socket factory does -
falling back to HTTP and so on. It could even do the remote-vs-local
address checking itself, and abort any attempts to connect to remote
machines. This obviously wouldn't be enough to guarantee security, as a
malicious attacker could just not use this factory.

Another really cool thing to do would be to write a pair of client and
server socket factories that used unix domain sockets (AF_UNIX), rather
than TCP/IP sockets (AF_INET). These are local-only by definition, and
ought to be faster (but probably aren't). They would only work on unix,
though. And there isn't AF_UNIX support in the standard java libraries.

You might also be able to do something by using RMI-IIOP and using the
controls your ORB provides.

tom
 
H

haimcn

A server socket bound to localhost will be able to receive connections
from outside. Unless you mean that <your port> would also be firewalled?
That should work.

How about using the version of UnicastRemoteObject.exportObject that takes
a pair of socket factories? The important one would be the
RMIServerSocketFactory; you could use that to make a special subclass of
ServerSocket that overrides accept() to check the client's address.
Something like:

public Socket accept() throws IOException {
        while (true) {
                Socket sock = super.accept() ;
                if (sock.getRemoteAddress().equals(sock.getLocalAddress())) {
                        return sock ;
                } else {
                        // might want to log the attempted connection
                        try {
                                sock.close() ;
                        } catch (IOException e) {
                                // might want to log this too
                        }
                }
        }

}

I'm not absolutely sure that this will always work; if you bind the server
socket to localhost, but open connections to yourself via an explicit
name, the addreses might not match. I don't really know how to deal with
that - what's a good general way of asking if an InetAddress refers to an
interface on the local machine? Perhaps you should just make the rule even
stricter, and say that only connections via the loopback interface will be
accepted; this avoids the problem.

The RMIClientSocketFactory would just open sockets in the normal way. It
wouldn't do the clever stuff that RMI's default socket factory does -
falling back to HTTP and so on. It could even do the remote-vs-local
address checking itself, and abort any attempts to connect to remote
machines. This obviously wouldn't be enough to guarantee security, as a
malicious attacker could just not use this factory.

Another really cool thing to do would be to write a pair of client and
server socket factories that used unix domain sockets (AF_UNIX), rather
than TCP/IP sockets (AF_INET). These are local-only by definition, and
ought to be faster (but probably aren't). They would only work on unix,
though. And there isn't AF_UNIX support in the standard java libraries.

You might also be able to do something by using RMI-IIOP and using the
controls your ORB provides.

tom

Thanks!!
I'll try that and report if it worked.
 
G

Gordon Beaton

A server socket bound to localhost will be able to receive
connections from outside.

A ServerSocket bound to a particular address can *only* accept
connections that arrive on the corresponding interface. If that
address is 127.0.0.1 then any remote connection attempts will result
in "connection refused". No firewall is necessary.

/gordon

--
 
T

Tom Anderson

Another really cool thing to do would be to write a pair of client and
server socket factories that used unix domain sockets (AF_UNIX), rather
than TCP/IP sockets (AF_INET). These are local-only by definition, and
ought to be faster (but probably aren't). They would only work on unix,
though. And there isn't AF_UNIX support in the standard java libraries.

Well, i had a very productive afternoon. Not much work done on my paper,
but i did knock together a little bit of unix domain socket support for
java:

http://urchin.earth.li/~twic/unixsocket.tar.gz

If you're not on OS X, you'll have to fiddle with the build script a bit.
If you're not on any kind of unix, the C code might be completely useless.

This is the nucleus of what would need to be done to add proper AF_UNIX
support to java. I think you'd want to do something with SocketImpl and
SocketImplFactory, although i'm not absolutely sure about that.

tom
 
R

Ronny Schuetz

Tom said:
A server socket bound to localhost will be able to receive connections
from outside.
No.

>Unless you mean that <your port> would also be firewalled?

No.

Ronny
 
T

Tom Anderson

A ServerSocket bound to a particular address can *only* accept
connections that arrive on the corresponding interface. If that address
is 127.0.0.1 then any remote connection attempts will result in
"connection refused". No firewall is necessary.

Aha! Of course! When Ronny said "localhost", i was thinking
InetAddress.getLocalHost(), which is (usually?) a proper interface, and
therefore accessible. But you read it, as he must have meant it, as
meaning the loopback interface. And absolutely, that's not accessible to
the outside world. Very clever, and rather obvious in retrospect.

I still think an AF_UNIX solution would be cool, though :).

tom
 
A

Arne Vajhøj

I'm writing a big application that I divide into 2 processes (server
and interface) with RMI to communicate between them.
I would like to limit the access to the server only from the interface
process and also only from the local machine.
Is there a way to limit RMI to localhost only?

Assuming that you use a RMISecurityManager, which you should if your are
security concerned, then you can control access in the security policy.

Arne
 
A

Abhijat Vatsyayan

Hi

I'm writing a big application that I divide into 2 processes (server
and interface) with RMI to communicate between them.
I would like to limit the access to the server only from the interface
process and also only from the local machine.
Is there a way to limit RMI to localhost only?

I cannot block all sockets outside the machine since I use them in the
server process.

Thanks!
Haim
As Arne has already pointed out, you should use RMI security manager.
This is something you want to handle declaratively, not programmaticaly
and as you have probably guessed, the solution has been there right from
day one (of RMI).

While implementing an OS level firewall will add additional security, it
will *not* fix all of your security problems. On linux/unix for example
(and this is just one), if there are other user accounts and some other
user account gets compromised, someone can setup ssh port forwarding to
fool the server into thinking that packets are coming form localhost. It
takes all of 5 seconds to do this.

Also - I do not know how you are creating your remote objects but most
people use the no-arg constructor (from UnicastRemoteObject) which means
you do not know in advance which port will the server listen on (see
Javadocs). So you only know the port on which rmiregistry is listening
and not the port on which the implementations are using.

These are just some of the problem but the general idea is to stay as
far away from (re)implementing security as possible. I know the fashion
these days is to stay away from JEE but security is probably one of the
most important reasons to use a JEE server (moving from RMI to EJBs is
pretty easy).

Abhijat
 
H

haimcn

Aha! Of course! When Ronny said "localhost", i was thinking
InetAddress.getLocalHost(), which is (usually?) a proper interface, and
therefore accessible. But you read it, as he must have meant it, as
meaning the loopback interface. And absolutely, that's not accessible to
the outside world. Very clever, and rather obvious in retrospect.

I still think an AF_UNIX solution would be cool, though :).

tom

Thanks all for your help!

I tried to implement custom socket factory and failed to bind the
object.
Is there any special thing I need to do in custom factory
implementation?

The factory code (it failed even when I just created the socket
without binding):

private static class LocalhostRMISocketFactory extends
RMISocketFactory {
@Override
public ServerSocket createServerSocket(int port) throws IOException {
InetAddress addr = InetAddress.getByName("127.0.0.1");
ServerSocket socket = new ServerSocket(port, 0, addr);
return socket;
}

@Override
public Socket createSocket(String host, int port) throws IOException
{
return new Socket(host, port);
}
}

The exporting code:

MyRmiInterface stubObj = (MyRmiInterface)
UnicastRemoteObject.exportObject
(this, 0, RMISocketFactory.getDefaultSocketFactory(),
new LocalhostRMISocketFactory());

The registry.rebind call failed with:
java.rmi.MarshalException: error marshalling arguments; nested
exception is:
java.io.NotSerializableException:
sun.rmi.transport.proxy.RMIMasterSocketFactory
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at project.rmi.RmiImpl.init(RmiImpl.java:134)
at project.core.Core.init(Core.java:465)
at project.core.Core.main(Core.java:247)
Caused by: java.io.NotSerializableException:
sun.rmi.transport.proxy.RMIMasterSocketFactory
at java.io_ObjectOutputStream.writeObject0(ObjectOutputStream.java:
1156)
at java.io_ObjectOutputStream.writeObject(ObjectOutputStream.java:
326)
at sun.rmi.transport.tcp.TCPEndpoint.write(TCPEndpoint.java:511)
at sun.rmi.transport.LiveRef.write(LiveRef.java:257)
at sun.rmi.server.UnicastRef2.writeExternal(UnicastRef2.java:48)
at java.rmi.server.RemoteObject.writeObject(RemoteObject.java:363)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io_ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:
945)
at java.io_ObjectOutputStream.writeSerialData(ObjectOutputStream.java:
1461)
at
java.io_ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:
1392)
at java.io_ObjectOutputStream.writeObject0(ObjectOutputStream.java:
1150)
at
java.io_ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:
1509)
at java.io_ObjectOutputStream.writeSerialData(ObjectOutputStream.java:
1474)
at
java.io_ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:
1392)
at java.io_ObjectOutputStream.writeObject0(ObjectOutputStream.java:
1150)
at java.io_ObjectOutputStream.writeObject(ObjectOutputStream.java:
326)
... 5 more
 
E

EJP

private static class LocalhostRMISocketFactory extends
RMISocketFactory {
java.io.NotSerializableException:
sun.rmi.transport.proxy.RMIMasterSocketFactory

That means it needs to implement java.io.Serializable. But you're doing
the wrong thing here. Make it *implement* RMIServerSocketFactory, and
provide a reference to one in the constructor of each remote object you
export. Don't use RMISocketFactory in any way.
 
A

Arne Vajhøj

I tried to implement custom socket factory and failed to bind the
object.
Is there any special thing I need to do in custom factory
implementation?

The factory code (it failed even when I just created the socket
without binding):

private static class LocalhostRMISocketFactory extends
RMISocketFactory {
@Override
public ServerSocket createServerSocket(int port) throws IOException {
InetAddress addr = InetAddress.getByName("127.0.0.1");
ServerSocket socket = new ServerSocket(port, 0, addr);
return socket;
}

@Override
public Socket createSocket(String host, int port) throws IOException
{
return new Socket(host, port);
}
}

The exporting code:

MyRmiInterface stubObj = (MyRmiInterface)
UnicastRemoteObject.exportObject
(this, 0, RMISocketFactory.getDefaultSocketFactory(),
new LocalhostRMISocketFactory());

The registry.rebind call failed with:
java.rmi.MarshalException: error marshalling arguments; nested
exception is:
java.io.NotSerializableException:
sun.rmi.transport.proxy.RMIMasterSocketFactory

I don't think the exception is related you your socket factory at all.

The problem is the third argument, which is supposed to be send
to client and therefore need to be serializable.

And apparantly the implementation
sun.rmi.transport.proxy.RMIMasterSocketFactory
is not so.

There are different way of specifying server socket factory
and bind objects. Just pick one that does not require
you to mess with client socket factory.

Arne
 
H

haimcn

I don't think the exception is related you your socket factory at all.

The problem is the third argument, which is supposed to be send
to client and therefore need to be serializable.

And apparantly the implementation
sun.rmi.transport.proxy.RMIMasterSocketFactory
is not so.

There are different way of specifying server socket factory
and bind objects. Just pick one that does not require
you to mess with client socket factory.

Arne

Can you please specify which ways are available?
Thanks!
 
H

haimcn

I answered that ten days ago.

Thanks

I tried to implement the socket factories and it worked when I didn't
bind it.
Then I bound the server socket to the local host and it stopped
working from localhost as well (the code is at the bottom).
The exception I got when I tried to access a method from the remote
class is described below.
It seems that the connection to the localhost is via DNS and not in
the loopback interface.

Where am I wrong?

Thanks!!

Exception:
==========
java.rmi.ConnectException: Connection refused to host: 10.xx.xx.xx;
nested exception is:
java.net.ConnectException: Connection refused: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:601)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:
198)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:
184)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:110)
at
java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:
178)
at
java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:
132)
at $Proxy0.getVersion(Unknown Source)
at mypackage.MyRemote.getVersion(MyRemote.java:122)
at mypackage.MyRemote.main(MyRemote.java:52)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:
195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:519)
at java.net.Socket.connect(Socket.java:469)
at java.net.Socket.<init>(Socket.java:366)
at java.net.Socket.<init>(Socket.java:180)
at mypackage.RmiService
$MyClientSocketFactory.createSocket(RmiService.java:72)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595)
... 8 more

Code:
=====

static public class MyClientSocketFactory
implements
RMIClientSocketFactory,
Serializable {

private static final long serialVersionUID = -2907595020431154956L;

public Socket createSocket(String host, int port) throws IOException
{
return new Socket(host, port);
}

public int hashCode() {
return (int) super.hashCode();
}

public boolean equals(Object obj) {
return (getClass() == obj.getClass());
}
}

static public class MyServerSocketFactory
implements
RMIServerSocketFactory {

public ServerSocket createServerSocket(int port) throws IOException
{
InetAddress addr = InetAddress.getByName(null);
return new ServerSocket(port, 0, addr);
}

public int hashCode() {
return (int) super.hashCode();
}

public boolean equals(Object obj) {
return (getClass() == obj.getClass());
}

}
 
C

conrad

I tried to implement the socket factories and it worked when I didn't
bind it.
Then I bound the server socket to the local host and it stopped
working from localhost as well (the code is at the bottom).
The exception I got when I tried to access a method from the remote
class is described below.
It seems that the connection to the localhost is via DNS and not in
the loopback interface.

It concerns me that the code sample you provide is not compilable,
that the classes you show use a very peculiar definition of equals(),
and that that definition is not consistent with their hashCode()
implementations.

Also, for readability, please reduce your indent level to a maximum of
four spaces.
Code:
=====

        static public class MyClientSocketFactory
                        implements
                                RMIClientSocketFactory,
                                Serializable {

                private static final long serialVersionUID = -2907595020431154956L;

                public Socket createSocket(String host, int port) throws IOException
{
                        return new Socket(host, port);
                }

                public int hashCode() {
                        return (int) super.hashCode();

Casting int to int is not really needed. Overriding hashCode() to do
nothing different is also completely unnecessary.

You wrote an entire class in order to implement a method that covers
for one expression:
'new Socket( host, port )'
and you don't even do any error-checking to justify the overhead of
the extra class. That is sub-optimal engineering.
                }

                public boolean equals(Object obj) {
                        return (getClass() == obj.getClass());

So any two members of this class are considered equal if they merely
belong to the same class? That doesn't make sense. I don't see any
reason to override equals() whatsoever.
                }
        }

The next class has the exact same problems - not compilable, performs
little to no useful work, and uses a peculiar and useless override of
equals() and hashCode().
        static public class MyServerSocketFactory
                        implements
                                RMIServerSocketFactory {

                public ServerSocket createServerSocket(int port) throws IOException
{
                        InetAddress addr = InetAddress.getByName(null);
                        return new ServerSocket(port, 0, addr);
                }

                public int hashCode() {
                        return (int) super.hashCode();
                }

                public boolean equals(Object obj) {
                        return (getClass() == obj.getClass());
                }

        }

And, of course, you provide absolutely no context for how you are
using the one line of code from each class that does anything useful.

I suggest that you work up an SSCCE
<http://pscode.org/sscce.html>
which will do two things - it will help you find your problem, and it
will help us find your problem.
 
H

haimcn

It concerns me that the code sample you provide is not compilable,
that the classes you show use a very peculiar definition of equals(),
and that that definition is not consistent with their hashCode()
implementations.

Also, for readability, please reduce your indent level to a maximum of
four spaces.








Casting int to int is not really needed.  Overriding hashCode() to do
nothing different is also completely unnecessary.

You wrote an entire class in order to implement a method that covers
for one expression:
 'new Socket( host, port )'
and you don't even do any error-checking to justify the overhead of
the extra class.  That is sub-optimal engineering.



So any two members of this class are considered equal if they merely
belong to the same class?  That doesn't make sense.  I don't see any
reason to override equals() whatsoever.


The next class has the exact same problems - not compilable, performs
little to no useful work, and uses a peculiar and useless override of
equals() and hashCode().








And, of course, you provide absolutely no context for how you are
using the one line of code from each class that does anything useful.

I suggest that you work up an SSCCE
<http://pscode.org/sscce.html>
which will do two things - it will help you find your problem, and it
will help us find your problem.

Thanks for your reply, I guess I did it wrong when I tried some code
sample modified not very well and took some code from my project.
I wrote a small standalone sample (without error handling) to
demonstrate the same problem (I hope I did it better now).
In the sample I implemented server socket factory so I'll be able to
bind it to the localhost and a client factory because it didn't work
without it.

The problem is still that it seems that the client is trying to bind
to the DNS address instead of the loopback interface and provides the
following exception:
Exception in thread "main" java.rmi.ConnectException: Connection
refused to host: 143.xx.xx.xx; nested exception is:
java.net.ConnectException: Connection refused: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:
601)
at
sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:
184)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:110)
at
java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:
178)
at
java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:
132)
at $Proxy0.sayHello(Unknown Source)
at test.Client.main(Client.java:14)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:
195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:519)
at java.net.Socket.connect(Socket.java:469)
at java.net.Socket.<init>(Socket.java:366)
at java.net.Socket.<init>(Socket.java:180)
at test.Server$MyClientSocketFactory.createSocket(Server.java:24)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:
595)
... 7 more


Interface:
==========
package test;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Hello extends Remote {
public abstract String sayHello() throws RemoteException;
}

Server:
=======
package test;

import java.io.IOException;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;

public class Server implements Hello {

static public class MyClientSocketFactory implements
RMIClientSocketFactory, Serializable {

private static final long serialVersionUID =
-2907595020431154956L;

public Socket createSocket(String host, int port) throws
IOException {
return new Socket(host, port);
}
}

static public class MyServerSocketFactory implements
RMIServerSocketFactory {

public ServerSocket createServerSocket(int port) throws
IOException {
InetAddress addr = InetAddress.getByName(null);
return new ServerSocket(port, 0, addr);
}
}

@Override
public String sayHello() throws RemoteException {
return "Hello";
}

public void init() throws RemoteException {
int port = 1099;
String name = "HelloInterface";
boolean exportRegistry = true;
try {
LocateRegistry.createRegistry(port);
} catch (RemoteException e) {
// failed to create the registry, no need to export it
exportRegistry = false;
}
Registry registry = LocateRegistry.getRegistry(port);
if (exportRegistry) {
UnicastRemoteObject.exportObject(registry, port);
}

RMIClientSocketFactory csf = new MyClientSocketFactory();
RMIServerSocketFactory ssf = new MyServerSocketFactory();
Remote stub = UnicastRemoteObject.exportObject(this, 0, csf,
ssf);

registry.rebind(name, stub);
}

public static void main(String[] args) throws RemoteException,
InterruptedException {
Server server = new Server();
server.init();

// keep server alive for a while
Thread.sleep(1000000);
}
}

Client:
=======
package test;

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {

public static void main(String[] args) throws RemoteException,
NotBoundException {
Client client = new Client();
Hello hello = client.init();
System.out.println(hello.sayHello());
}

private Hello init() throws RemoteException, NotBoundException {
int port = 1099;
String name = "HelloInterface";
String host = null;

Registry registry = LocateRegistry.getRegistry(host, port);
Hello hello = (Hello) registry.lookup(name);

return hello;
}
}
 
E

EJP

You wrote an entire class in order to implement a method that covers
for one expression:
'new Socket( host, port )'
and you don't even do any error-checking to justify the overhead of
the extra class. That is sub-optimal engineering.

That is *unnecessary* engineering. I already told the OP he didn't need
a client socket factory. The one he wrote is practically identical to
the default.
So any two members of this class are considered equal if they merely
belong to the same class? That doesn't make sense. I don't see any
reason to override equals() whatsoever.

Then you need to learn more about the semantics of RMI socket factories.
This is the standard form for RMIClientSocketFactory.equals(). But the
OP doesn't need the class at all.
The next class has the exact same problems - not compilable, performs
little to no useful work, and uses a peculiar and useless override of
equals() and hashCode().

You're right but for the wrong reasons. RMIServerSocketFactories
shouldn't be compared on a class basis, only client socket factories.
Server socket factories should be compared on a protocol basis. If they
don't superimpose a protocol over TCP, or the protocols are equal, they
are equal.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top