Configuring RMI for Tunneling over HTTP
Remote Method Invocation (RMI) is the Java middleware that allows one object to invoke methods directly on remote objects without any difference in syntax. RMI handles the underlying communication, determines how parameters will be accessed, and provides the serialization of data necessary for the method call so that it can be transported from client to server and back again.
|
The information in this section is relevant to both HTTP and HTTPS.
|
Java 8 and lower versions
If a direct TCP/IP socket connection cannot be established between the client and the host and part of an RMI server, RMI calls can be transported over the HTTP protocol. Although the Java RMI specification is clear about this tunneling, the default Java implementation depends on some Java system property settings. Therefore, RMI does not automatically fail over.
RMI servers within Windchill overcome this limitation by allowing the socket factory, which is used for RMI communication between client and server, to be configurable. Socket factories supplied by the Windchill bootstrap package (boot.jar) that support RMI-over-HTTP can be used. The following property is set as the default to control the socket factories exported by Windchill RMI servers:
wt.rmi.clientSocketFactory=wt.boot.WTRMIMasterSocketFactory
|
RMI-over-HTTP tunneling is enabled only when:
• The boot.jar is included as one of the client JARs.
• The boot.jar is installed in the client’s classpath (for example, installed in the lib/ext directory of the JRE).
Otherwise, only direct RMI socket connections to the host and port of the RMI server are supported.
|
Windchill includes the socket factory WTRMIMasterSocketFactory, which improves on the J2SE default connection failover logic. This socket factory:
• Supports tunneling of RMI calls over HTTP and HTTPS regardless of system properties.
• Supports configurable URL paths for Java RMI CGI compatible proxy script.
• Uses asynchronous connection attempts for all socket factories to reduce total connection time on the initial connection.
The WTRMIMasterSocketFactory uses a series of secondary socket factories to connect to the RMI server. The connection failover is used:
1. If WTRMIMasterSocketFactory does not have sufficient privilege to perform any of the required operations, the installed default socket factory is used instead.
2. If the wt.boot.socketFactory system property is read on the client, and if the fully qualified class contained within the setting can create an instance of a RMISocketFactory, that socket factory is used for client to server communication.
3. If the client configurable socket factory fails, the socket factory starts a direct socket connection (wt.boot.WrappedRMIDirectSocketFactory).
4. If the direct connection fails, or does not complete within the failover time-out (as defined by wt.boot.failoverTimeout), the socket factory starts an HTTP connection to the RMI target port in case the client is behind an HTTP proxy server (wt.boot.WrappedRMIHttpToPortSocketFactory).
5. If the HTTP to port connection fails or does not complete within the failover time-out, it starts an HTTP connection to the Java RMI CGI gateway found on the server which supplied the client codebase (wt.boot.WTRMIHttpToCodebaseSocketFactory).
6. If the HTTP to codebase connection fails or does not complete within the failover time-out, it simultaneously starts HTTP and (optionally) HTTPS connections to the default Java RMI CGI proxy (wt.boot.WrappedRMIHttpToCGISocketFactory and wt.boot.WTRMIHttpsToCGISocketFactory).
The first connection type that completes successfully is used, and the resulting socket factory is reused for all subsequent connections to that host.
Java RMI Servlet
When directly connecting to RMI servers is not allowed, the web server must respond to requests for /cgi-bin/java-rmi.cgi to make the forwarding of HTTP requests possible. An actual CGI file is provided in the Java SE Development Kit (JDK). The Java RMI specification expects this file to be added to the web server cgi-bin directory. By setting wt.rmi.javarmicgi to another URI, the CGI file can exist anywhere, for example /servlet/JavaRMIServlet.
To improve performance, security, and flexibility, Windchill delivers a servlet that can be mapped to the same URL. The servlet class is wt.tools.javarmi.JavaRMIServlet. This class adds security as it can be configured through servlet initialization parameters that forward connections to a predefined range of destination port numbers. However, the java-rmi.cgi file provided in the JDK allows the HTTP request to identify any port number on the local host, opening other services to potential attack.
To improve performance, wt.tools.javarmi.JavaRMIServlet does not start a new process for each RMI call. To add flexibility, it allows itself to be configured to forward requests to a nonlocal RMI server host, thereby acting as an RMI proxy server. The servlet parameters are:
• serverHost
• minPort
• maxPort
The values for minPort and maxPort are automatically calculated based on the wt.properties configuration for the method server RMI ports.
Java 11
RMI over HTTP tunneling for Windchill client is not supported as the sun.rmi.transport.proxy package is removed for Java 11 and later. However, a similar functionality is supported for Java 9 and later using Spring Remoting. Spring Remoting has RMI mechanism to communicate Java serialized object between client and server. If Java 11 JRE or higher is used and RMI port is blocked, the flow goes to Spring Remoting. Sprint Remoting uses HTTP post request to transmit Java serialized object.