Will we need to use the --enable-native-access option to enable JNI in the future?
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Mon Sep 20 17:28:28 UTC 2021
On 20/09/2021 18:06, Glavo wrote:
> Because my English is very poor, I may not know enough about the
> exact meaning of words. If my words are too offensive, I apologize.
>
> What I'm more intersted in is - what make you think that adding
> extra command line flags would be perceived as such a blocker? Do
> you have examples in mind where this might turn out to be
> problematic in practice?
>
> I think there are a lot of possible blockers:
>
> * Most obviously, we have lost the ability to simply execute with
> java -m.
> Now we can only go back to the classpath and describe it in
> MANIFEST.MF (if supported in the future).
> If it is not supported, we even lose the ability to double-click
> to open the jar on windows.
> We can only consider wrapping the jar with a third-party solution.
I believe that to be the case in most applications requiring native
libraries? How do you express native library dependency only using -m ?
> * Maybe I missed something. I remember there were relevant
> discussions before,
> but there still seems to be no way to enable native access for
> modules at runtime in Java 17.
> If so, how to enable a module defined at run time using custom
> ModuleLayer to use Panama?
> If not, it will be a devastating blow to any dynamic plugin
> mechanism, e.g. Minecraft mods.
There is no way now, given the mechanism is in its infancy, no reason it
couldn't be added in the future, when working with module layers.
> * This assumes that I always know all the modules when I start the
> program,
> but this is not necessarily the case. For example, the most
> typical is the ServiceLoader.
> Some components expect to work only by putting them on the module
> path,
> such as a implementation of FileSystem or a ScriptEngine.
See above.
> * Windows cmd limits the maximum length of a single command to 8192.
> We have some use cases to export a single bat script file that can
> be started
> by double clicking for novice users. We are often close to this
> boundary, and continuing
> to increase the length of the command line will exacerbate this
> problem.
This is true of any new command line flag, picking on this specific one
for that limit seems a bit harsh.
> * and more...
>
> Saying that, since JNI is unsafe and enabled-by-default, then
> Panama should just follow suit, seems like an ill-conceived
> argument. Because something else is not great (for historical
> reasons - modules weren't there when JNI was born), doesn't, in my
> opinion, justify making everything else bad too, just because of
> that precedent.
>
> In fact, I am not entirely opposed to restricting native access.
> However, the premise is that this option, like its name, really needs
> to enable native access. However, at present, even without it,
> it does not mean that the module cannot to native access.
> This naming is extremely misleading. It can't bring real security to
> users.
>
> Note also that, in JNI, most of the unsafety comes from within JNI
> C glue code (e.g. the so called JNI functions). This glue code is
> no longer there in Panama - since it can be simply expressed as
> Java code. So, the Panama API faces a risk which was much less
> real with JNI: having seemingly innocent, pure Java code crashing
> the JVM. All this reasoning is explained, in greated details, in
> JEP 412.
>
>
> I understand this, which is the only reason I can partially agree.
> If it just block me at compile time, need me to explicitly enable it
> with annotations or compiler parameters, and I'd like to see that.
> But why do my end users need to confirm my choice?
> Does TA need to be clearly aware that my library, as a third-party
> library,
> is using java code instead of native code to implement binding?
I think that, if your library is implemented using native code, who uses
your library has to have a shot at deciding whether that's ok or not
(given the safety issues that can arise). Of course, as already
discussed, the provided safety guarantees can't be absolute, because of
JNI and Unsafe, but hopefully we'll get there.
>
>
> I won't talk about how realistic it is for JNI to migrate to Panama.
> How to define the _new_? Do you think this is the era of Java 17?
> No, this is the era of Java 8, 11 and 17. Before 2031, in these nine
> years,
> there is no reason to support Java 8, but only reason to give up.
> In these nine years, any blocker will have a significant impact on
> the promotion of an alternative without introducing new capabilities.
By new I mean new. Developers that are ok having dependencies on the
latest version. I don't see how the fact that there are multiple LTS out
there affects the way in which the --enable-native-access option will be
perceived, frankly.
>
> Let's also think of users of the Panama API who couldn't care less
> about native interop (there are some in this mailing list) - e.g.
> developers who only use the foreign API to allocate, access and
> free memory off heap. Very likely, these developer would like to
> take advantage of the extra protection provided by the
> --enable-native-access flag, to make sure they don't accidentally
> depend on unsafe functionalities they do not require.
>
>
> The same as above, why can't you restrict it at compile time and put
> it at run time?
>
The same as above - because if it's compile-time then it becomes a
choice of the developer of the library, and the application packager,
which assembles many libraries, doesn't have a say of which can and
cannot access native features of the Java platform.
Honestly, calling any of the issues above "blockers" seems harsh - some
of these can be figured out (such as having a story for granting native
access to modules in dynamic layers), others such as command line limit,
surely cannot be put down on Panama alone.
The only remark which is worth pointing out is your general feeling that
enabling native access is a compile-time only business; of course we
thought about this at the very beginning when we started thinking about
enabling native access explicitly, but we found this solution not
satisfactory; it would be the equivalent of enforcing module boundaries
only at compile-time - because then, if the library developer has opted
to break some boundaries, why should that decision be forced on 3rd
parties? But module boundaries are enforced _both_ at compile time _and_
at run time. So, in my view, while at some point we might have a static
story too (e.g. javac might start barking about native access, and a
flag will be added there too to match the runtime flag), having some
sort of runtime flag is an integral part of the safety feature we're
after here.
Maurizio
More information about the panama-dev
mailing list