<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hi Ron,<br>
</p>
<div class="moz-cite-prefix">On 01.09.2023 14:08, Ron Pressler
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">The integrity of the platform is very important to us for the multiple reasons that I mentioned before, one of which is precisely because we’d like code that runs on Java N to also run, unchanged, on Java N+5. One of the main causes for that not happening in the past has been a lack, not excess, of integrity. We want to get to a place where most Java programs would, by default, be assured that they’re portable and enjoy all the safety guarantees that Java can offer.</pre>
</blockquote>
<p>That has been the goal of Java since day one and Java has been
keeping its promise of "compiling once and running on every
platform" since! So this is nothing new you bring to the Java
table.<br>
</p>
<p>The major break was with the module system where some Java
applications would not be allowed to execute anymore. The reason
being that they got developed with rules that got changed way
after the Java applications got implemented. These rule changes
were not foreseeable many years back but regarded to be so
important that the OpenJDK community took the risk to break. <br>
</p>
<p>To give everyone plenty of time to adjust and to (maybe) rework
the Java classes according to the new rules the support for Java 8
got extended (currently until at least December 2030 by Oracle and
Azul, cf.
<a class="moz-txt-link-rfc2396E" href="https://en.wikipedia.org/wiki/Java_version_history"><https://en.wikipedia.org/wiki/Java_version_history></a>).<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Yes, unfortunately that means introducing some inconvenience. </pre>
</blockquote>
<p>The problem here is - and it is interesting that you seem to not
be willing to understand - that this is not "some inconvenience",
it is a message to users of Java based applications and Java
classes that what they are using is dangerous, even if this is not
true at all. In today's world issuing the words "danger" or
"warning" by authorities in public will put almost everyone into
panick mode, then into petrification mode and then into action
mode to move away (from Java in this case) to some "safer"
solution.<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">The inconvenience is not the goal, it’s just a necessity, and we’re sorry we have to impose it. We’re doing our best to keep it as minimal as we can.</pre>
</blockquote>
Unfortunately, I do not see that you are really doing the best that
you can. You can do much better! :)<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Moreover, we’re still in the midst of a transition from an era when integrity was not the default but only opt in — which, sadly caused a rather big inconvenience to the Java ecosystem — to a position where integrity is the default. Again, we try to keep this inconvenience to a minimum. We’re encouraged to see the positive effect that strengthened integrity by default has already had on the ecosystem.
I realise that encountering this somewhat changed world may be scary for some, </pre>
</blockquote>
<p>The "some" that you scare are those who pay in order to use
Java/OpenJDK applications and who will switch ASAP.</p>
<p>[See what happened to the browser Java plugin: reports of
security problems with Java turned up (as wrong as they might have
been in many instances) by third parties/media and after some time
allowed the browser producers like Google, Apple and Microsoft to
remove Java from the browser by removing the documented plugin
interfaces harming Java heavily on that the very important browser
market segment. So these "some" were the wrong "somes".]<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">but the big improvements we deliver — including FFM, ZGC, records, patterns, virtual threads, JFR, and some other big ones coming soon — should more than make up for that, not to mention very significant performance improvements that you get for free.</pre>
</blockquote>
<p>These improvements are welcome, however, please realize that
every new feature that Java gains, not only makes Java more
powerful, but at the same time more complex, more difficult to
learn all that there has become available since Java's birth. This
also makes Java more and more difficult to teach of course.</p>
<p>And BTW neither records, nor patterns, etc. have anything to do
with client's native code impacting them.<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">If we want to deliver all that so that Java could thrive by adapting to a changing environment — in terms of hardware, deployment, and security — we must make many changes, and they require platform integrity.
However, our analysis may still be wrong. It’s certainly possible that a flag problematic enough to negate all the benefits we’re delivering. That is why we usually try not to impose new rules right away but to start with warnings. Those warnings help us evaluate what the effect of some change really are and not what we, or anyone else, speculate they would be. If using the flag to disable the warning turns out to be a serious problem — we’ll be able to reevaluate with actual feedback from the field in hand. We’ve done this process several times over the past few years, and it ended up working well.</pre>
</blockquote>
<p>The potential damage that this does will not allow you to correct
it, if in the public minds it has become a fact, that Java is
really incredibly risky, so dangerous that even Java itself warns
about using Java! Once that kind of damage is done, it can hardly
be corrected if at all.<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">BTW, if you have an example of a program that business administration students write and doesn’t work unchanged on JDK 22, I’d love to know what it is. </pre>
</blockquote>
<p>As the JEP does not rule out to turn the warning into an error
eventually, this has to be expected whenever in post-22 this
change will take place. <br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Making Java easier for beginners is another focus area for us (see <a class="moz-txt-link-freetext" href="https://openjdk.org/jeps/445">https://openjdk.org/jeps/445</a>).</pre>
</blockquote>
<p>Yes, I have been following this and I applaud this initiative. <br>
</p>
<p>More than twenty years ago I used Java to teach beginners
programming (business administration students) with a team of
tutors. The problem back then (and still today) is that there is a
steep learning curve coming with it (and BTW also for C++, C#,
even for programming languages that professionals think that they
are easy to learn for beginners like VBA and Python) which
consumes so much lecture time that you barely can get to teach the
most important programming concepts because you lost too much time
for explaining infrastructural needs and/or peculiarities of a
programming language. Just to write a program that puts a simple
text on the screen and that allows for reading from the keyboard
is extremely involved if you are a novice who has never heard
anything of hardware and software.</p>
<p>OTOH, learning Java (and other compiled and strictly typed
languages) as a second language is very feasible. The easier its
syntax and needed infrastructure, the better.<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Also, I’m afraid that the JRE ceased to exist in JDK 11. You can talk of the JDK or of a Java runtime, but the JRE was a very particular Java runtime (it was a global Java Runtime ENVIRONMENT) with certain features that simply no longer exists. </pre>
</blockquote>
<p>Sorry, this is simply not the reality. Until Java 8 Java there
were always two installation packages that differed only in the
developer utilities bundled with it. The JDK has always been the
JRE with the compiler and developer tools like javadoc etc. So one
would get a JRE in any case, one without and one with development
tools.<br>
</p>
<p>Both versions got installed system wide with the effect that Java
has been always available to all processes. So "JRE" describes the
phenomenon that Java is installable globally and as such makes all
its features available to third party software: Java applications,
but also non-Java applications that interact with the JRE. It is
exactly for this usage that JNI got invented in the first place
and has since served very well both, the Java world and the Java
client world.</p>
<p>What is a little bit frightening, it seems that you are not aware
of the non-Java-app use of Java at all. Probably because of this
you may not be able/willing to accept that there is a clientele
that would be overwhelmed and frightened if your proposal would be
realized in its current form.<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">I believe that some vendors now distribute Java runtimes that they call a JRE just to minimise the surprise that the JRE is gone, but I assure you that those runtimes are not JREs, and that the JRE is, indeed, a thing of the past. Java runtimes, however, still offer some of the things the JRE did, so perhaps you are referring to those. Or perhaps you mean the Java 8 JRE, which is still available.</pre>
</blockquote>
<p>Again, the JRE global installation is what has been available
from day one. Starting with Java 9 the global installation
includes the compiler and the developer tools. <br>
</p>
<p>Unfortunately, starting with Java 11 the four JavaFX modules got
removed from most installation packages which is causing quite
some damage to the Java ecosystem! Rather than being able to rely
on JavaFX to be available everywhere in any modern JDK
installation such that one's GUI needs can be easily implemented
with JavaFX all of a sudden one is "bombed back" to only be able
to rely on awt/swing to be present for sure. It is really a giant
step backwards and no one in the Java/OpenJDK groups seems to take
even notice, let alone to care about it. (Modular Java allows
easily for leaving out modules that some specific application
would not need including any JavaFX modules. But this is different
from the globally installed JDK where all of a sudden important
pieces get artificially cut out and are simply not available,
cannot be relied to be available anymore making the usage of Java
insecure as you cannot rely that modules are present in JDK+5 as
you write.)<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Now, let me try and answer your specific questions:
1. If the "user" is the "application author" who is one who creates a pure Java application and controls its setup, the JRE to use, why is it then necessary to warn Java "application authors" about something that may not be even true, that the JNI module in use would be dangerous and/or a security risk?
First, let’s define what we mean by “integrity”. It is the ability to make a promise (that is then kept). For example, the JDK makes the promise that all instances of String are immutable. This invariant (a property that always holds true) is, in turn, enforced by the integrity invariant that all private fields are only accessible by their declaring class. Both user code and JDK code depends on the invariant that all Strings are immutable for its correctness. However, any library that uses JNI can decide, nah, I will access private fields and I will mutate Strings. </pre>
</blockquote>
Who in his own right mind would try to mutate Strings, even if it
was possible?<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Another example of an integrity invariant (and we can argue over it’s as important as the first) is that the JDK would like to promise that the JVM process never crashes or that the GC never hangs the application (short of a bug in the JVM). </pre>
</blockquote>
*Exactly*, short of a bug! You cannot promise therefore "absolute
integrity" as this thread of discussions implicitly communicates.
You can try to guarantee as much as possible, but never absolutely.<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">If any JNI-using library is used, a bug in the library may also cause the process to crash or the GC to hang. </pre>
</blockquote>
<p>This is true, and it is true for the Java runtime itself as it
necessarily employs JNI. Therefore it has been standard to test
libraries (native or pure Java) thoroughly, even coming up with
testing frameworks to test such libraries whenever changes get
applied.</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Yet another invariant is that a program that runs on one version of Java and on one kind of OS/hardware platform is portable to another. This invariant may also not hold when a JNI library is used.</pre>
</blockquote>
<p>This has nothing to do with "integrity", it has been a big
selling point of Java from day one! <br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Therefore, when you use a library that employs JNI, you enter a world where most or even all of the promises that the JDK otherwise makes may not hold. </pre>
</blockquote>
<p>Why is that? Just because you fear that to be the case? And even
if JNI code does not adhere to all rules of Java, it does not mean
that this is done to intend and to effect any harm to Java.<br>
</p>
<p>In this context you should also state that Java must only be used
by Java applications and you must make sure that the Java runtime
adheres to this as well?</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">This is a different mode where invariants that give Java code its usual meaning at *any* point in the program — not just code that directly calls the library — may no longer hold, and we want the application author to know that they’re application is running in such a mode.</pre>
</blockquote>
<p>So you assume that the application author is an idiot or is
totally clueless?</p>
<p>So you *must* force the application author to acknowledge that
s/he uses native code? What good does that do for the integrity of
the author's application?<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Because there are situations that the JDK can also perform better optimisations when its promises can be trusted, it is also important for the author to know whether the application can enjoy such optimisations or not.</pre>
</blockquote>
<p>This has nothing to do with "integrity" per se either, it is
looks like rhetorics.</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">2. People know that one can kill with a knife, why would you want to warn everyone forcefully that knives can kill people, if the normal, expected usage of a knife is for cutting meat and vegetables? (If an "application author" uses modules from sources she or he does not trust, then such a human would be expected to check thoroughly such modules, if they should be used nevertheless, wouldn't she or he?)
Because the way Java applications are composed means that it’s very difficult for the application’s author to know what their libraries do and what invariants they may break. Typically, the application author picks a few libraries and lists them in a build-tool configuration, but they then require further “transitive dependencies”. I.e. an application that’s set up to use five libraries may actually use 50. Not only that, the number and composition of those transitive dependencies may change when any library is upgraded. So the same application that asks for five libraries, may end up using 50 today and 60 tomorrow. Can any of those transitive dependencies break the invariants that Java makes and the author wants to trust (because, say, they want to ensure their application is portable)? It’s very hard to tell without a full analysis of the code of all the transitive dependencies.
In other words, it’s extremely hard for the author to know whether their application is carrying knives or not, and if so where to look if its handling them safely.</pre>
</blockquote>
<p>Hmm, extremely hard? Regarding JNI, how about looking for
{System|Runtime}.load[Library()] or methods with a "native"
modifier? How about an application author being forced to bundle
the target platform's and architecture's native libraries? <br>
</p>
<p>You really mean that an application author would not know that
JNI gets used? And if s/he would want to know would not be able to
find out?<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Furthermore, it is impossible for the Java runtime to know whether the knives are used safely or not. </pre>
</blockquote>
The Java runtime will *never* know whether using the Java language
itself is being used safely for realizing applications. <br>
:)<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">That’s the whole point of various unsafe mechanisms, including native code: that they’re free of further safety checks. So because the vast majority of libraries don’t need knives at all, </pre>
</blockquote>
<p>How come you are so sure that that is the case at all? Can you
give real world examples?<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">imposing a conservative policy is efficient </pre>
</blockquote>
No, this has nothing to do with the first half of your sentence.
Nothing here is "efficient" as long as you do not state the unit of
measurements and what gets measured.<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">(BTW, in my country it’s illegal to carry a knife unless you can explain your use).</pre>
</blockquote>
<p>(This would be seen as rather strange in my country!) <br>
</p>
<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">3. For an application author to learn about JNI being used in some of the modules it would be sufficient to get a warning/information when running a tool that would tell her or him. Such an application author would be able to learn from module-info entries (maybe via a tool) which modules document their use of JNI. In such a scenario it then would be probably acceptable that in the case that if modules at runtime use JNI without having this usage documented in their module-info that then a warning gets issued to make the application author aware of it (and only if the module is at least at the class file level of the Java version that introduced this feature and should have been aware of this newly introduced documentation obligation).
As the JEP states, we would like to offer modular libraries the ability to declare their use of JNI, or, more precisely, to declare that they request such permission, </pre>
</blockquote>
<p>This can be simply done with an entry in module-info.<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">but the application would still need to grant that permission, because the whole point is that a library should not be allowed to decide for itself in which mode the entire application is running in: </pre>
</blockquote>
Who else can determine that if not the author of such a library?<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">one where promises are kept or one where they may not be. </pre>
</blockquote>
<p>Again, interestingly enough, this has nothing to do with the
problem at hand. Who promises what and how can it be controlled
that the promises are kept?<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">And because of the way applications are assembled as I described above, requiring the user to analyse all of their transitive dependencies over and over is placing too much of a burden on them. </pre>
</blockquote>
No, it is not. <br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">The goal of this JEP is to make the life of those who want to enjoy integrity (which is the majority of application) much easier, </pre>
</blockquote>
<p>It may be the case that you think of the group of (expert) people
who want to go ahead and do all sort of nifty runtime
configuration things?</p>
<p>For normal application developers and for normal users of the JRE
you do not make anything easy or easier, you complicate and put
burden on the shoulders and in the case of end-users you are about
to shy them away from Java/OpenJDK.<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">and only impose a very slight inconvenience on those who want to grant some libraries superpowers.</pre>
</blockquote>
<p>It is not a "slight inconvenience". That "simple warning" as it
is proposed currently has the potential of destroying the
reputation of Java. Once the reputation is destroyed, you cannot
reinstate it by saying "oops, we made a little mistake".</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">3. What integrity guarantees does the JDK give that a JNI author would want to intentionally and forcefully break with the intent to harm the JDK? (And if a JNI author would do that intentionally to harm the JDK then she or he can be traced down and made accountable for it.)
If only things were that simple (and it’s all explained in the integrity JEP, BTW). Let me speak not about JNI specifically but all unsafe mechanisms in the JDK because the reasons and effects are the same: Some libraries want to do away with the JDK’s invariant that all newly allocated memory, either on heap or off heap, is initialised for performance reasons. </pre>
</blockquote>
No one I know of would want that in a plain JNI library that is
supposed to be deployed in the field.<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">A bug in the *use* of such a library may cause your secret keys to be sent over the wire. What’s even more interesting is that such libraries are rarely used directly: </pre>
</blockquote>
That is not interesting, that is what JNI is about.<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">you use some high-level library that, under the covers, uses a low-level library that allocates memory without initialising it. </pre>
</blockquote>
Again, which JNI author in the world would rely on a Java
application to initialize physical memory and then forgetting about
it? Please give me a break!<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Now, note how complicated the situation has become: the low level library is not at fault — yes, they break an invariant, but they warn their users to use the library correctly. </pre>
</blockquote>
<p>Firstly, you assume that the native code always breaks something
holy to "Java integrity" without any data to back up your
assumption. It is just one of many unreal scenarios you come up
with (like the scenarii you cite in which JNI authors want to
change final fields, String values and create JNI programs in the
most stupidest way). Just claiming something is (potentially!) the
case without backing it up with hard data is not enough in a
serious, sorber discussion.<br>
</p>
<p>As you probably know, the JNI library would be even able to exit
the JVM if an error would be so devastating that for security
reasons carrying on executing code cannot be done reliably anymore
- or in your words jeopardizing "integrity". (That has been the
purpose of creating crashes since the inception of computers and
programs that run on them, a means of last resort.)</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">The high-level library has a bug in the use of the low-level library, but the high-level library itself never breaks any invariants. </pre>
</blockquote>
<p>Says who? This again is such an unlikely scenario as is the
scenario that user use knives to kill other people. (There are
8,000,000,000 people on this world who use knives to cut their
food, how many use it to kill people which you need to know in
order to come up with a probability of someone being prone to be
killed with a knife. Not talking about probabilities just focusing
on the possibility of killing someone with a knife - as a knife
can be used for that purpose as well - is not enough for an
educated, sorber discussion or justifying a warning on each knife
that knives can be used to kill people.)<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Finally, the application never even asked for a library that breaks JDK invariants.</pre>
</blockquote>
<p>Again, this has nothing to do with reality. An application that
uses a Java library/module that employs JNI will use it because it
adds benefit to the application developer's implementation in a
secure manner. The Java library as well as the JNI library is
tested and if errors show up they will get fixed during
development and during maintenance. <br>
</p>
<p>An application will never "ask for a library that breaks JDK
invariants". If errors occur the application's author will report
them and use the fixed versions of both Java frameworks and the
JNI libraries, whoever is responsible for uncovered errors.</p>
You cannot make away for these situations with any flag.<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">And if you think that’s the worst of it, well, get a load of this. Some serialization libraries, say, those that can deserialise JSON, need to set private (perhaps even final) fields and instantiate objects without calling a constructor. </pre>
</blockquote>
<p>This is BTW something I have never understood: why would Java
developers employ the concept of private fields in such cases? The
getter/setter pattern has been devised for that, yet, Java
programmers (also from Sun and Oracle) have employed this strange
pattern.</p>
<p>E.g. in my JNI library the clients of the library can only access
public members (and protected members only, if they subclass the
appropriate Java class in an ooRexx class). If the client tries to
access private fields then it is only possible via the public
getter or setter methods.<br>
</p>
<p>So, I regard any Java author who misuses private members in this
way a rather bad Java programmer as there is no need for breaking
such an invariant at all. But if the Java author has done it then
JNI is forced to break that invariant. Who is the bad guy and the
good guy then, the Java author or the JNI author?<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">This, of course, requires breaking access control, the invariant that supports all others. So they use a low-level library with superpowers that break access control. So far, everyone has the best intentions. However, the JSON library deals with input that arrives to the application from the outside world, and that input determines which fields it sets and which objects it instantiates without a constructor. A vulnerability in that innocent library can direct its action toward critical JDK classes, and because the operation is done by using a super-powered low-level library, there are no longer any access checks in its way. So, everyone here is well meaning — the application and both libraries; the vulnerability is not in the super-powered library. But now a vulnerability in one library can have a catastrophic effect because there is some transitive dependency with superpowers.</pre>
</blockquote>
<p>This example is also one that nicely demonstrates how integrity
can be easily broken. Just assume that the producer of the JSON
file made errors in the produced JSON encoding's structures and/or
values.<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">It can actually get worse and more complicated than that (the library with the vulnerability need not even use the superpowered library). </pre>
</blockquote>
<p>Without superpowers your JSON example demonstrates nicely the
problem at hand: Java cannot guarantee the integrity even of Java
applications (that is the responsibility of the authors). <br>
</p>
<p>E.g. if the JSON data gets used for controlling radiation dosis
and radiation times in a hospital and the encoded data contains
wrong, deadly information, the patients will die. Would you then
state, because Java's "integrity" rules are guaranteed, that such
a Java application cannot not break integrity anymore?</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">4. If a module employs JNI without reporting it that may be regarded as not behaving like a good citizen in the modular Java land and hence reporting the fact that module xyz employs JNI without telling in its module-info at runtime.
First, most libraries aren’t modular. </pre>
</blockquote>
<p>Yes. But those libraries that have been compiled prior to 22
should not be affected as the authors had no idea that someone
came up with this idea in this form in the meantime. <br>
</p>
<p>As it is a goal, please correct me if wrong, to convince Java
programmers to adopt the module framework, then it would be the
case that any framework author would package it as a module. <br>
</p>
<p>If using 22 or later then the compiler and/or jlink could be used
to emit warnings with the information that the warning goes away
if defining module-info.java with entries (could be even shown)
that declare the use of native code. <br>
</p>
<p>This may have then the effect that you get more developers to
adopt modules. <br>
</p>
<p>But in this scenario it is the module not a user of a module that
needs to declare that. And if compiled with 22 or later and no
module-info is present or does not contain the declaration then
the warning would be o.k. as it then can be easily inhibited by
the author. <br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Second, we’ve tried a social approach for many years, and it doesn’t work. </pre>
</blockquote>
<p>What did you try for "many years"? I have noticed nothing in that
respect.</p>
<p>Maybe you were discussing this among your peers (bubble?) such
that over time you got the impression that everyone ought to know
about it by now, not realizing that many such discussions are
confined to the mailing lists that got created for it and not
everyone is able to follow (or knows about appropriate mailing
lists)?<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">I mentioned before that one of the most important invariants is portability: if a program works on JDK N, it would work on JDK N+5 (with very high probability). </pre>
</blockquote>
That has been the case for my JNI library since Java 1.1, on OS/2,
Windows, Linux and macOS. <br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">What happened before we started having integrity by default is that libraries — for their own good reasons — reached into non-standard JDK internals. </pre>
</blockquote>
<p>This is what you claim but for which you have not supplied any
data. Any JNI developer whose library gets used in real world
applications must make sure that its use is prudent, checking for
errors before interacting with Java, but also checking for errors
in arguments when invoked by native methods, not doing any
intentional harm to anyone.</p>
<p>If in JNI a library author does not adhere to the Java
definitions then there is usually a good, compelling reason: if
the Java developers insist on using private fields without public
getters and setters, but expect these private fields to be filled
via JNI, what is wrong then? Clearly, how the Java (!) developers
have gone about designing the interface to their framework.</p>
<p>The JNI implementers will make sure that the interfacing to and
from Java works without errors. (And if errors get uncovered they
get fixed ASAP as is the case in any application.)<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">These may have been a few low-level libraries, but more high level libraries used them, and even more applications used those. </pre>
</blockquote>
<p>Again, please state numbers and names for such dangerous
"low-level libraries" and "more high level libraries using them"
and "even more applications using those". <br>
</p>
<p>Sentences like these sound very dramatic, yet lack hard figures.
It is about pure speculations probably igniting more speculative
discussions and in the end everyone agreeing how dangerous
everything is. :)<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">The result was that when JDK 9 was released (which made many internal changes but *no* changes to access) a lot of applications broke. </pre>
</blockquote>
<p>Yes, and most of those applications that broke, broke
unexpectedly from the perspective of the authors, because they
simply were not able to follow any discussions in these OpenJDK
mailing lists. The information for those Java authors was lacking.</p>
<p>As many deployments will not get updated as long as they do fine
Java/OpenJDK 8 has become so important today. Rather than everyone
flocking to modular Java, it has been a stuttering process
witnessing various Java framework libraries and the need of
supporting pre-modular Java deployments. It is also the reason why
Java/OpenJDK 8's support has been extended to 2030.</p>
<p>For deployed such Java applications that do not run on modular
Java it makes sense to keep them on Java 8 as long as possible. In
the meantime either getting modular versions eventually or moving
away from Java altogether which gets easier if Java gets the odem
of being insecure (do not forget, the browser companies had to
pull the plugin support to remove the Java security risk and the
users/journalists accepted without protest).<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">All they knew was that a change to Java broke their program. </pre>
</blockquote>
Yes and it was Java/OpenJDK itself that introduced that breaking
change for them.<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Maybe the information that “using this may make you non-portable” was never published by the low level libraries. Maybe it was but it wasn’t repeated by the high level libraries. Maybe it was but application developers didn’t notice or didn't. Whatever the reason, the result was that “Java broke backward compatibility” even though you may think that everyone made a conscious choice to be not portable (and in reality, the application authors certainly didn’t).</pre>
</blockquote>
<p>Well, it was the case that one was supposed to use
java.lang.reflect and that was what many of those applications
that broke would have used. Then java.lang.invoke surfaced,
nowadays predominant in MethodHandles and the like, BTW
overwhelming many classic, pre modular educated Java programmers.<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Whoever is to blame, we want to offer a way for this not to happen again, </pre>
</blockquote>
<p>Clearly Java/OpenJDK experts in these mailing lists are to be
blamed not the pre-modular Java programmers.<br>
(And as far as I am concerned for quite a few good reasons! :) )<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">that for most programs (and for the vast majority of *new* programs) means they need to do nothing. Maybe modules will allow us to do something cleverer for modular libraries someday, but because most libraries and applications aren’t modularised, we need to offer them integrity by default, too.</pre>
</blockquote>
<p>Yes, I see a benefit in communicating as good as possible to
application authors that their application may not be portable in
the case that native interaction is exploited. But then, please,
warn those developers also from using Java/OpenJDK itself as it
uses native access if Java/OpenJDK does not announce this
explicitly in its module-info.</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">We fully realise that integrity is a very complex subject, which is why so much work has been put into making it simple, which, in this case, requires nothing more than a flag. </pre>
</blockquote>
<p>It is interesting that you insist that what you propose is
"simple", "requiring nothing more than a flag", when it has been
repeatedly communicated, that this is not true. You (and some
others) seem to constantly ignore the fact, that this is not a
simple, harmless change. <br>
</p>
<p>(Maybe I should come up with a few simple examples that
demonstrate the use cases I am thinking about.)<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">The goal is to balance the needs of the majority of applications, which can and should enjoy integrity, </pre>
</blockquote>
<p>You pretend that anyone who does not apply the flag is not
enjoying "integrity"? <br>
</p>
<p>Or that whoever has to supply that flag is not "enjoying
integrity"? So what are the consequences, leaving the Java
platform and enjoy someone else's "integrity" like .Net/CLR, Rust?<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">and the minority that need some less integrity. </pre>
</blockquote>
<p>Why do you think this is a "minority"? And what does "less
integrity" mean? Again, purely speculative, no hard numbers that
you have been able to cite so far.</p>
<p>The argumentation is mostly about emotions (dangerous to use the
superpowers to change a String's value, "less integrity", etc.)
and not about facts.<br>
</p>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Furthermore, we’d like applications that employ the class path (the majority) and not just the module path to also be able to enjoy integrity. </pre>
</blockquote>
Who would not want to enjoy that? And why, do you insinuate that
others who do not obey your rule/view to not use native code do not
enjoy integrity for their applications? <br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Previously, integrity was opt-in, and it required such complex configuration that few could ever get it right. </pre>
</blockquote>
Again, suggesting the fear "complex configuration that few could
ever get right", which is simply not true. Please back such claims
with hard numbers, not speculative, emotional arguments.<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">Now we need it to be the default, and the minority of applications that need to opt out can do so easily. </pre>
</blockquote>
It is a little bit autistic to read over and over again wrong
assumptions of yours (and probably others in the bubble) that a
"minority of applications" is affected and that it would be easy to
"opt out easily". Neither is true.<br>
<blockquote type="cite"
cite="mid:34C21C55-9457-4444-8723-A6743532BF89@oracle.com">
<pre class="moz-quote-pre" wrap="">The majority will be able to rest easy that their programs are portable and don't crash.</pre>
</blockquote>
<p>Again the devil on the wall that applications will (not might,
will!) "crash", if they do not supply that switch or refrain from
using native code, which would mean to cease using Java/OpenJDK.</p>
<p>---</p>
<p>What you omitted to comment were among other things:</p>
<ul>
<li>module-info (documenting the use of accessing native code
JNI): why do you not comment on this idea which would allow for
documenting explicitly its usage, such that simple tools can be
made to create reports that also document use of JNI (and which
then also should list the Java/OpenJDK modules). It would easily
solve the unlikely situation that an application developer is
not aware of the use of JNI in Java frameworks s/he uses; with
JNI the application author gets immediately confronted with the
need of the JNI library for different operating systems and
architectures, if s/he wants the Java application to be sold on
those platforms; so how can any application developer be able to
ignore this? Argumentations like this therefore appear somewhat
artificial, not of real-world quality, looking a little bit like
straw men).<br>
<br>
</li>
<li>How can an application developer possibly evaluate whether a
JNI library is safe or unsafe without having the necessary
skills and being able to look into the source-code? Such
application developers get effectivley blackmailed to use that
"simple switch" if they want to stop terrifying warnings for
their users and later even show-stopper errors of their
applications without any good reason. The same is true for any
pure Java framework BTW where in today's complex world the
expertise is missing or access to source-code is not available
or the size makes it incromprehinsible (difficult if not
impossible to check out the integrity of such systems). <br>
The only thing an application developer can assess is the
trustness of the components s/he uses. Warnings like the
proposed one will undermine the established trust for Java and
Java applications I am afraid. <br>
</li>
</ul>
---rony<br>
<p><br>
</p>
<br>
</body>
</html>