Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Find a better workaround for macOS access to OpenJDK #10

Closed
ctrueden opened this issue Oct 22, 2018 · 9 comments
Closed

Find a better workaround for macOS access to OpenJDK #10

ctrueden opened this issue Oct 22, 2018 · 9 comments

Comments

@ctrueden
Copy link
Member

When running imagej.init on a macOS system without Apple Java 6 installed, an error is given when attempting to load Java via JNI:

No Java runtime present, requesting install.

And a dialog box appears saying "You need to install the legacy Java SE 6 runtime." Unfortunately, this is no longer possible on current versions of macOS.

A workaround is to edit the Info.plist of your Java installation to include <string>JNI</string> in the capabilities, as described at kivy/pyjnius#277 (comment). However, there is no guidance to do this. And it would be better if we could automagically make things work without requiring the user to perform an administrator-level action.

@ctrueden
Copy link
Member Author

It seems another workaround is to link to libjli instead of libjvm; see e.g. dotnet/java-interop#198. This might be better since it will not require hacking the installed JRE.

@ctrueden
Copy link
Member Author

It turns out that the ImageJ launcher has already used this libjli hack for years; see imagej/imagej-launcher@efaea16. I don't know how I missed this for so long. But pyjnius would need to use it as well; see kivy/pyjnius#277 (comment).

@jamesbraza
Copy link

jamesbraza commented Sep 10, 2019

@ctrueden I am hitting this problem on pyimagej==0.4.0. I followed your install instructions, using miniconda --> conda create -n pyimagej pyimagej openjdk=8.

How can I use dotnet/java-interop#198 in the contexts of the pyimagej environment?

Here is some info on my machine:

  • OS: macOS Mojave version 10.14.3
  • echo $JAVA_HOME --> /usr/local/Caskroom/miniconda/base/envs/pyimagej
  • java -version -->
openjdk version "1.8.0_192"
OpenJDK Runtime Environment (Zulu 8.33.0.1-macosx) (build 1.8.0_192-b01)
OpenJDK 64-Bit Server VM (Zulu 8.33.0.1-macosx) (build 25.192-b01, mixed mode)

@ctrueden
Copy link
Member Author

@JDusub83 On the user side, I do not know a way for you to link to libjli instead of libjvm—I think this is a change we'd need to make upstream in pyjnius.

The way I currently work around this issue is:

brew cask install adoptopenjdk8
sudo sed -i '' -e 's/\(<string>CommandLine<\/string>\)/\1<string>JNI<\/string>/' /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Info.plist

In other words: install a system-wide JVM and then add <string>JNI</string> to the JVMCapabilities section of its Info.plist.

Note that this works equally well with adoptopenjdk cask with adoptopenjdk-12.jdk folder—it doesn't matter which Java you hack in that fashion; it won't actually be used by pyimagej. It's just a hack to make Apple's overzealous linkage check happy.

I am sorry this is still necessary. ☹️

@ctrueden
Copy link
Member Author

I quickly checked how hard it would be to fix on the pyjnius side, and it turns out it was extremely simple, so I filed a PR: kivy/pyjnius#441. Hopefully they will merge it soon.

@jamesbraza
Copy link

jamesbraza commented Sep 10, 2019

Thank you @ctrueden for getting back quickly and also for opening up a PR for a long-term fix!

A few notes


brew cask install adoptopenjdk8

Per this article, I also had to brew tap AdoptOpenJDK/openjdk first.


sudo sed -i '' -e 's/(CommandLine</string>) ...

I previously had jdk "12.0.1" 2019-04-16. I ran this command (I just modified directory path):

sudo sed -i '' -e 's/\(<string>CommandLine<\/string>\)/\1<string>JNI<\/string>/' /Library/Java/JavaVirtualMachines/jdk-12.0.1.jdk/Contents/Info.plist

And found it did this:

        <dict>
                <key>JVMCapabilities</key>
                <array>
                        <string>CommandLine</string><string>JNI</string>
                </array>

Not sure that it matters that the </string><string>JNI</string> is not on a new line, you may want to add that to the sed command.

Regardless, I tested it out (without the new line), and found that the change worked anyways.


So anyways, thank you for suggesting the temporary fix! Feel free to post again when the PR goes through, and I can test it out.

@jamesbraza
Copy link

jamesbraza commented Sep 10, 2019

@ctrueden I tried to make the sed command better. Full disclosure, I don't really know sed.
Using this answer, and manually adding in exact amount of whitespace, I got close:

sudo sed -i '' -e 's/\(<string>CommandLine<\/string>\)/\1\'$'\n''                        <string>JNI<\/string>/' /Library/Java/JavaVirtualMachines/jdk-12.0.1.jdk/Contents/Info.plist

There is probably a better way to do the newline and maintain whitespace, but I couldn't figure it out. Perhaps you would know a better way to do this.

@ctrueden
Copy link
Member Author

ctrueden commented Sep 10, 2019

I also had to brew tap AdoptOpenJDK/openjdk first.

Right, thanks for pointing that out.

There is probably a better way to do the newline and maintain whitespace, but I couldn't figure it out. Perhaps you would know a better way to do this.

Inserting lines with BSD sed is annoying, which is why I didn't bother. The Info.plist is XML, so the whitespace doesn't matter.

Regardless, I tested it out (without the new line), and found that the change worked anyways.

Glad to hear! 😄

@ctrueden
Copy link
Member Author

I filed a PR to pyjnius that was merged: kivy/pyjnius#441

Once a new pyjnius is released, this issue will go away! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants