Disallowing the dynamic loading of agents by default

Alan Snyder javalists at cbfiddle.com
Tue Apr 4 16:27:46 UTC 2017

> On Apr 3, 2017, at 3:36 PM, mark.reinhold at oracle.com wrote:
> In addition to future performance improvements, let's not forget about
> maintainability.  Improved integrity allows those of us who maintain the
> JDK to change internal implementation details without having to worry
> about breaking user code.  It allows users of the JDK to be confident
> that their code depends only on supported interfaces, so that they can
> more easily upgrade from one release to the next.  We've all too often,
> over the last twenty years, had to back out internal changes because
> some popular library depended upon those internals.
> A common response to this concern is to say, "then don't use libraries
> that depend upon JDK internals!"  Would that it were that simple.  The
> hardest cases arise when some library A that depends on JDK internals is
> published, then it's used by library B, which in turn is used by library
> C, and that in turn is used by the immensely-popular library D, whose
> authors don't even know that library A depends on JDK internals.  (They
> might not even know that D ultimately depends on A!).  Then we fix a bug
> in the JDK that changes those internals, library D breaks, a large number
> of popular applications (or applications with important customers) stop
> working, and the cries and support escalations demanding that the change
> be reverted ensue.

Sounds to me like there are two different issues here.

One issue is the ability to create a library that breaks when “internal implementation details” of the JDK are changed. The other is the awareness of when one is depending upon such a library.

It should be clear that it is impossible to prevent libraries from depending upon internal implementation details and impossible to always be aware of when a library is so dependent. You will always have to worry about breaking user code, but maybe you can worry less.

A realistic goal would be to reduce the likelihood of a developer accidentally depending upon internal implementation details. Another would be to make it more likely that when a developer chooses to depend upon implementation details (sometimes necessary if the goal is to have code that works on already deployed platforms) that the dependence uses a mechanism that is detectable by static examination of the library. These goals may be related. Perhaps a developer would be less likely to create an avoidable dependence knowing that users would be aware of it.

These goals can be accomplished by erecting barriers but also providing well defined and statically visible bypasses, of which there are several long standing examples. Perhaps more control of these bypasses is needed. Perhaps some kind of module permission scheme would help. If I release a version of a library that bypasses a barrier (for reasons that are hopefully temporary), I should be willing to statically declare my need to do so (just as “apps” declare their need to access the network, etc.). If I release a runtime tool that needs to bypass a barrier, perhaps my users should be willing to use a security manager that allows my tool to do what it needs. (I understand the desire for a solution that does not require a security manager, but I’m less clear on why one should not allow a security manager to participate in the solution.)

In this regard, I find “integrity” as a concept or goal to be misleading or even meaningless. By erecting more barriers are you actually “improving integrity”? I don’t think so. The ability to write implementation-dependent code remains and always will remain. A barrier can have a benefit: reducing accidental or hidden implementation dependencies. But a barrier can also have a cost, which, ironically, is to cause existing code to break in the new JDK! So, worry is conserved, at least temporarily.

More information about the jigsaw-dev mailing list