4
$\begingroup$

This is kind-of a strange question, so please bear with me.

We have a Java application that has a utility for Mathematica 12 that lets you run our app from Mathematica using JLink. This works fine on macOS and Windows. On Linux we get an exception, thrown from the java.util.prefs.Preferences class.

After much nosing around, I noticed the JVM from Mathematica on Linux was setting -Djava.util.prefs.PreferencesFactory=com.wolfram.jlink.DisabledPreferencesFactory, and in the Mathematica SystemFiles I found that DisabledPreferencesFactory class to be returning the null value causing our exception.

That's when I found this code in InstallJava.m (lines 518 to 527) in the JLink folder (in a createCommandLine function used by InstallJava[]):

(* Disabling the Java prefs subsystem on Unix/Linux is a hack to work around a very annoying problem with
   that subsystem. Maybe Sun will fix this in JDK 1.5. Because this is an experimental fix, we'll put in
   the $disablePrefs flag as a backdoor that could be set from top level before launching Java.
*)
prefsSpec =
  If[!osIsWindows[] && !osIsMacOSX[] && $disablePrefs =!= False,
    " -Djava.util.prefs.PreferencesFactory=com.wolfram.jlink.DisabledPreferencesFactory",
  (* else *)
    ""
  ];

That made it clear where the issue is coming from, and it looks like we even have a way to disable this, as we're on Java 1.8 and I don't think the issue discussed is still a problem, so I'm fine setting that $disablePrefs flag to false.

So my question is, how do I set that $disablePrefs flag in a way that the JLink package will see it and not set this Java argument? I tried doing it inside a Mathematica 12 document before loading our package ($disablePrefs = False;), and then also modified our package to set that flag before calling InstallJava[] from JLink, but neither worked. I'm hoping this is a simple Mathematica thing I just don't know how to do, as I haven't used it much. Thanks.

$\endgroup$
  • 1
    $\begingroup$ You should use the fully-qualified symbol name for this internal variable. After loading JLink, if you evaluate Names["*`$disablePrefs"] then you find it is called JLink`InstallJava`Private`$disablePrefs . Try setting that to false before calling install java. $\endgroup$ – Jason B. Feb 27 at 21:41
  • $\begingroup$ That worked splendidly, thank you, and thanks for the extra info about how to find the fully-qualified name in the future. If you want to write your comment up as an answer, I'll be happy to accept it. $\endgroup$ – Jasper Feb 27 at 21:59
4
$\begingroup$

From the comments around the code snippet posted, I would guess that $disablePrefs is not an exported function from the JLink package, but instead is a private variable. To find the name of the internal variable run

In[4]:= Names["*`$disablePrefs"]

Out[4]= {"JLink`InstallJava`Private`$disablePrefs"}

after you've loaded JLink. That part is important because if you haven't loaded the package then the symbol was never created. Now that you know the name of the symbol, set it to False before calling InstallJava[] and it should trigger the else clause of the `If` statement.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.