JDK-8165649 : Re-examine if Activatable object can be created from non-public class and/or constructor
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.rmi
  • Affected Version: 9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2016-09-08
  • Updated: 2017-02-23
  • Resolved: 2017-02-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 10 JDK 9
10Fixed 9 b157Fixed
Related Reports
Relates :  
Description
JDK-4164971 allows non-public activatable class and/or constructor, create the activatable object.

This issue is to re-examine if the same should be allowed from the Activatable implementation class/constructor to be non-public.  Also whether the specification matches the current implementation.
Comments
Review thread, combined with JDK-8044626: http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-February/046178.html
01-02-2017

An alternative location where the accessibility requirements of the special activation constructor can be documented is in the newInstance() method spec of java.rmi.activation.ActivationInstantiator. This is probably preferable to updating the RMI specification, since 7.3.3 mixes a lot of specification with description and explanation.
27-01-2017

Part of the RMI activation mechanism involves calling the "special activation constructor" of an Activatable class. This is defined in section 7.3.3 of the RMI specification, in the subsection entitled "Constructing an Activatable Remote Object." (Search for "special" on this page for other mentions.) Essentially this constructor must be of the form MyActivatableClass(ActivationID id, MarshalledObject mo) and it's called reflectively by the RMI Activation system when an object is to be activated. The activation system calls setAccessible(true) on this constructor before invoking it. This allows the Activatable class and/or its special constructor to be private. (The relevant code is in sun.rmi.server.ActivationGroupImpl.) Preliminary investigation seems to show that a Activatable classes are loaded by name from the RMI codebase using the RmiClassLoader mechanism. By default, this uses an internal RMI ClassLoader (sun.rmi.server.LoaderHandler.Loader), a subclass of URLClassLoader, which loads classes from the codebase. It also (probably) delegates to the application ClassLoader, which can load classes from the classpath. Any classes loaded this way will most likely end up in the ClassLoader's unnamed module, so the reflective invocation as described above will work unchanged. It might be possible for an Activatable object to reside in a module, if that class isn't present on the codebase, and the RMI class loader delegates to the application class loader, which might find that class (and its enclosing package) in a module on the module path. If this is the case, one of the following must be true: a) the module must be open, b) the module must have opened Activatable's package to the java.rmi module, or c) the module must export the Activatable's package, the Activatable class must be public, and its special constructor must be public. Since automatic modules are open, an activatable object may reside in an automatic module. RMI also provides an SPI for applications to define their own class loading. Whatever they do here needs to ensure that the Activatable class's constructor is accessible to the activation system, along the lines of what's described above. In principle it seems possible to change the RMI implementation to add an "opens" edge to a module that contains an Activatable object. This doesn't seem necessary, though. Activatable objects will by default reside in the unnamed module, so things will just work. If someone migrates an activatable object to an automatic module, things will still work. If someone migrates an activatable object into a named module, presumably they are in control of the declarations in module-info.java, and declarations could be added here to open the Activatable object's package to java.rmi. Requiring a declaration to be added is reasonable, since the Activatable object is essentially part of this module's public interface, though it's called reflectively, not statically. The RMI specification should be updated to explain the minimal requirements on Activatable objects, distilled from the above. No code changes are necessary.
27-01-2017