Is there any replacement for HTTP tunneling with RMI in Java 9?
Asked Answered
O

2

6

So I see that HTTP tunneling over RMI has been removed in Java 9.

We sell commercial Java software, which runs in Tomcat. Our customers install this on their Mac, Windows, and Linux servers. This software is then accessed by the public, with a Java Swing client interface. It uses RMI for communication with the server software.

Most of our customers have firewalls preventing access to the server on any port other than 80/443. This is not a problem for Java 8 and earlier, which can use RMI over dynamic ports or switch to HTTP when a firewall blocks access.

However, removing the HTTP proxy feature in Java 9 means that most of our customers will no longer be able to use our software, as currently architected. It is impractical and insecure for our customers to configure their firewalls and servers for SSH access from the public, especially for customers running Windows servers.

Does this mean that we need to rewrite our application architecture to use some network protocol other than RMI? Or is there a way to keep RMI in Java 9? Ditching RMI entirely will require a complete rewrite of our user-facing application code, and is not a cost effective option.

Oozy answered 18/11, 2017 at 3:50 Comment(2)
Just curious... Why do you want to upgrade to Java 9 for your solution?Hardesty
Because our product does not work on Mac OS X High Sierra in Java 8. We tested with Java 9 and that did work, so it seems like we need to port to Java 9.Oozy
A
6

Seems like JDK-8023862 already deprecated HTTP proxying from RMI as also mentioned in the release notes of Java8.

As suggested in #JDK8180642 which also inquires of an alternative to removal of HTTP proxy implementation from RMI. One of the alternatives could be to use ssh to tunnel through the proxy.

Use ssh to establish a local port that is tunneled through the proxy to the remote machine. The connection will be more functional than the HTTP proxy implementation.

In the chained links you can find an article over how can one make outgoing Java RMI calls through a local firewall? which suggests other implementations such as SOCKS and socket factories as well.

Approximate answered 18/11, 2017 at 5:9 Comment(4)
I don't see anything in that documentation suggesting that RMISocketFactory can be used for HTTP tunneling. It states that HTTP tunneling has been deprecated (which is incorrect, as far as I can tell it has been removed entirely). SOCKS / custom socket factories are not helpful if the server is behind a firewall that only allows access on port 80/443.Oozy
@JesseBarnum True. Would correct that, seems like the documentation has not been updated accurately. And using ssh to tunnel through would be the first thing to try out while you see a restore in Java9 I believe.Approximate
SSH wouldn't work in our case because our software is installed on our customers' servers and then accessed by the public. It would be impractical to configure all of our customers' servers to allow SSH access from unknown public usersOozy
@JesseBarnum The design that you follow seems a little too complex, though it would be good to understand the same if you could update the question with how and why exactly do you follow the approach. The goodness that you get out of it currently sounds very bound to the use case to me.Approximate
L
5

So I see that HTTP tunneling over RMI has been removed in Java 9.

Not surprising. It was a poor solution, one-way, with a 10x performance penalty.

Does this mean that RMI is dead?

No. It is part of Java as of 1.1 and the history of Java since then, twenty years ago, is a remarkable record of backwards compatibility. The last breakage in ABI compatibility was when they changed the AWT event model between 1.0 and 1.1. It would be astonishing if RMI was ever removed from Java, and there is nothing in the removal of RMI/HTTP tunneling that justifies you in jumping to this conclusion.

We currently use RMI extensively for building client-server user interfaces. It's common for our clients to have firewalls blocking dynamic ports, so we revert to HTTP tunneling.

You will certainly need another solution for tunneling. SSH comes to mind.

How should we deal with this in Java 9?

See above.

Ditching RMI entirely will require a complete rewrite of our user-facing application code.

There is nothing to suggest such a necessity.

Regarding RMI port usage:

  1. There is port sharing by default.
  2. You can specify the port when exporting, either via super(port,...) if you extend UnicastRemoteObject, or UnicastRemoteObject.exportObject(object, port, ...) if you don't.

So for example if you export a Registry and then more remote objects from the same JVM, they will by default share port 1099, or you can explicity force it.

If you are using an RMIServerSocketFactory you need to provide it with an appropriate equals() method to preserve these semantics.

Leix answered 18/11, 2017 at 8:54 Comment(7)
SSH wouldn't work in our case because our software is installed on our customers' servers and then accessed by the public. It would be impractical to configure all of our customers' to allow SSH access from unknown public users.Oozy
The majority of our customers will only allow access on port 80 or 443 to the server. Since RMI normally requires dynamic ports to be available on the server, HTTP support has been removed, and SSL tunneling is impractical and inadvisable for access from the public, I don't see any way to use RMI in Java 9.Oozy
RMI doesn't require dynamic ports. You can use 1099 for everything, or any other free port. Your customers will have to open some other port besides the HTTP ports.Leix
NB You're askng new questions here.Leix
It's possible that I'm wrong (been a few years since I wrote the code), but in my recollection, port 1099 is only used to get an instance of the object that is registered with the RmiRegistry. Once that is complete, the actual remote method calls are done on ports that are dynamically allocated at run time.Oozy
No. (1) There is port sharing by default, and (2) you can specify the port when exporting. So for example if you export a Registry and then more remote objects from the same JVM, they will by default share port 1099, or you can explicity force it.Leix
I didn't know that. I'll experiment with that. Thank you. If you want to put that as a separate answer I'll mark that as accepted.Oozy

© 2022 - 2024 — McMap. All rights reserved.