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

Using JPL with Java 8 on Mac OS X issues #2

Closed
pmoura opened this Issue Oct 5, 2015 · 18 comments

Comments

Projects
None yet
5 participants
@pmoura
Copy link

pmoura commented Oct 5, 2015

On Mac OS X there is a command, java_home, that returns the path for the user's enabled and preferred JVMs in the Java Preferences application. This command is Apple's advised way of defining the JAVA_HOME environment variable. On my system I get:

$ /usr/libexec/java_home
/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home

The user can add to its ~/.profile file (or equivalent) the line:

export JAVA_HOME=`/usr/libexec/java_home`

SWI-Prolog build script picks the value of the JAVA_HOME environment variable but there's a problem. The generated libjpl.dylib looks into the wrong place as you can check by typing:

$ otool -L libjpl.dylib
libjpl.dylib:
    /System/Library/Frameworks/JavaVM.framework/Versions/A/JavaVM (compatibility version 1.0.0, current version 1.0.0)
    ...

This can be corrected by typing:

$ install_name_tool -change /System/Library/Frameworks/JavaVM.framework/Versions/A/JavaVM /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/server/libjvm.dylib libjpl.dylib

Still, if you try a JPL call (e.g. jpl:jpl_call/4), your SWI-Prolog process will end with an error that "No Java runtime present, requesting install." and a system prompt to install Java 6! If you sigh, throw your hands in the air, surrender, and install Java 6 then JPL will happily work using Java 8. I suspect some lingering linking issue that the fix above is not enough to correct. Is possible that the problem is in the following line in the JPL Makefile:

JAVALIBS=-Wl,-framework,JavaVM

But I have no idea how to fix and still generate a .dylib. Any hints?

@JanWielemaker

This comment has been minimized.

Copy link
Member

JanWielemaker commented Dec 7, 2015

As it seems the jpl build is now broken on my machine and it merely includes the old version, this seems a good time to look into this. The first question is which version of Java one is supposed to install how on MacOS? Somehow, my El Captain as a "Java for OS X 2015-001" disk on the desktop. Trying to install it results in some warnings that this is a legacy old version and one should download Java from java.com. Is that what I should be doing for building JPL? Is that what people who actually use Java on MacOS do?

If I get it build, I might be able to add code to jpl.pl that automates the step above to fix the link target for libjpl.dylib.

@anionic

This comment has been minimized.

Copy link
Contributor

anionic commented Dec 7, 2015

On 07/12/2015 16:30, Jan Wielemaker wrote:

As it seems the jpl build is now broken on my machine and it merely
includes the old version, this seems a good time to look into this.
The first question is which version of Java one is supposed to install
how on MacOS? Somehow, my El Captain as a "Java for OS X 2015-001"
disk on the desktop. Trying to install it results in some warnings
that this is a legacy old version and one should download Java from
java.com. Is that what I should be doing for building JPL?

Of "Java for OS X 2015-001", Apple say:

This package is exclusively intended for support of legacy software
and installs the same deprecated version of Java 6 included in the
014-001 and 2013-005 releases.

If you need Java, download the latest version of Java for OS X
directly from Oracle https://www.java.com

Oracle's is kinda the reference implementation.

For now, JPL should work fine with Java 6.

Is that what people who actually use Java on MacOS do?

Yes if they take Apple's advice ;-) but I guess some will install the
"deprecated version of Java 6" because they (think they) need it, or
because it's easier, then not install any newer version.

If I get it build, I might be able to add code to jpl.pl that
automates the step above to fix the link target for libjpl.dylib.

Are you aiming to (be able to) build a binary SWI Prolog for Mac OS X
x64 which happily links to either legacy Java 6 or recent Oracle/Sun
Java 8?

I have received an early Xmas prezzie of a 7 yr old MacBook Pro on
which I have a fresh El Capitan OS X - can I help?

Paul Singleton

@JanWielemaker

This comment has been minimized.

Copy link
Member

JanWielemaker commented Sep 29, 2017

I pushed some stuff that may hopefully resolve this. Building on the Mac now finds and uses the Oracle Java. There is a library for the Mac jpl_config.pl that provides jpl_config_dylib/0 that updates libjpl.dylib. The check_installation/0 linked help page is updated and if JPL fails to load it points at jpl_config_dylib/0 if you are using a Mac.

I hope that is enough ...

@pmoura

This comment has been minimized.

Copy link

pmoura commented Sep 29, 2017

After git pull, deleting my installed version, and rebuilding, I get:

% Loading library(jpl) ......................... FAILED
Warning: Cannot load required shared library
Warning: See http://www.swi-prolog.org/build/issues/jpl.html

Calling the jpl_config_dylib/0 indeed fixes the problem for all subsequent runs.

@JanWielemaker

This comment has been minimized.

Copy link
Member

JanWielemaker commented Sep 29, 2017

Thanks for testing. Should we consider this `good enough' or is there an easy way to make this better? Note that we might not be able to write to libjpl.dylib, there may be no Java at all, etc. If you think this is good enough, please close.

@pmoura

This comment has been minimized.

Copy link

pmoura commented Sep 30, 2017

Any reason to not automate calling the jpl_config_dylib/0 predicate when building on macOS?

@dmpotter44

This comment has been minimized.

Copy link
Contributor

dmpotter44 commented Nov 14, 2017

I'm still encountering this with Java 9. However, it looks like it may in fact be a regression in the JDK itself, as apparently earlier Java 8 JDKs would trigger the "No Java runtime present" dialog when started via JNI (JDK-7131356).

@JanWielemaker

This comment has been minimized.

Copy link
Member

JanWielemaker commented Nov 14, 2017

That seems unrelated. This topic was about finding the Java .dylibs. As the path to find them must be compiled into libjpl.dylib binary distributions need to go through a process of finding the right JDK and updating libjpl.dylib.

@dmpotter44

This comment has been minimized.

Copy link
Contributor

dmpotter44 commented Nov 14, 2017

There's still an issue with jpl_config_dylib/0 not checking the Java 9 libjvm.dylib location, but I don't know enough Prolog to make it check both locations. (Instead I manually edited the file to only check the Java 9 location.) However it still fails with the "No Java runtime present, requesting install." terminal message. By using DYLD_PRINT_LIBRARIES I can verify it is loading the right JVM, and then blowing up anyway.

@JanWielemaker

This comment has been minimized.

Copy link
Member

JanWielemaker commented Nov 14, 2017

As I understand it, Java9 dropped jre from the path? I can fix that in jpl_config_dylib/0. Otherwise, I don't know.

@dmpotter44

This comment has been minimized.

Copy link
Contributor

dmpotter44 commented Nov 14, 2017

Correct. As far as I can tell JPL works under Java 9, but so far I've only been able to use it from the Java side - trying to use JPL within SWI-Prolog directly causes the "No Java runtime present" message.

@JanWielemaker

This comment has been minimized.

Copy link
Member

JanWielemaker commented Nov 15, 2017

Update jpl_config_dylib/0. That, as I understand, won't fix the problem. I have no clue about that though.

@dmpotter44

This comment has been minimized.

Copy link
Contributor

dmpotter44 commented Nov 15, 2017

I'm fairly certain at this point that the problem is within the JDK itself. I just realized that the majority of the examples use Swing, and when I run examples/prolog/jpl_versions_demo.pl, everything runs just fine. So as of now, JPL works under Java 9, as long as you don't try and run something that uses Swing. (And possibly other parts of the JDK.) This is definitely not a JPL issue, but it's something people should probably be aware of.

@JanWielemaker

This comment has been minimized.

Copy link
Member

JanWielemaker commented Nov 16, 2017

Might be an Apple Java issue. There have been problems with swing this in the past too. Shall we close this?

@dmpotter44

This comment has been minimized.

Copy link
Contributor

dmpotter44 commented Dec 1, 2017

As long as you don't touch AWT, this appears to work. The latest version also solves the problem I had where Homebrew wasn't building JPL with the --with-jpl flag: it was attempting it, but it would fail, and then the SWI-Prolog build would just skip JPL.

As far as I can tell, everything now "works" with JPL and Java 9 under macOS, minus an internal macOS JDK bug that can be triggered if you call any code that uses AWT (which includes Swing):

$ java --version
java 9.0.1
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)
$ swipl --version
SWI-Prolog version 7.6.3 for x86_64-darwin16.7.0
$ swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 7.6.3)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit http://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- use_module(library(jpl)).
true.

?- jpl_new('java.awt.Frame', ['Hello AWT'], F).
No Java runtime present, requesting install.
$

However, if you avoid AWT, it works fine:

?- use_module(library(jpl)).
true.

?- jpl_new('java.io.File', ['demo.pl'], F),
jpl_call(F, toPath, [], P),
jpl_call('java.nio.charset.Charset', forName, ['UTF-8'], Utf),
jpl_call('java.nio.file.Files', readAllLines, [P,Utf], Ls),
jpl_call(Ls, get, [ 0 ], L).
F = <jref>(0x7f915869c810),
P = <jref>(0x7f915869c818),
Utf = <jref>(0x7f91584c3358),
Ls = <jref>(0x7f915869c820),
L = ':- asserta(file_search_path(foreign, \'.\')).'.
@ssardina

This comment has been minimized.

Copy link
Contributor

ssardina commented Oct 12, 2018

Is this true Jan? My students taking the course now (Sept 2018) said that:

"As the homebrew version does not come with the JPL library (an issue on the homebrew github as been opened about this), the second step is therefore to buid the library from source. Alternatively, you can download the already compiled libjpl.dylib and copy it in:"

I am asking because your post is from Dec 2017

I do not have a Mac but they (students) devised this plan to make it work:

https://github.com/ssardina-research/packages-jpl/wiki/JPL-under-Mac-OS

@pmoura

This comment has been minimized.

Copy link

pmoura commented Oct 12, 2018

MacPorts is an alternative to Homebrew for installation on macOS. Did you tried it to check if it also have an issue with JPL? I'm the maintainer of the portfile. But, as I use the git version, there have been quite some time since I last used the MacPorts install.

@JanWielemaker

This comment has been minimized.

Copy link
Member

JanWielemaker commented Oct 13, 2018

Is this true Jan? My students taking the course now (Sept 2018) said that:

It is true that you can just graph a libjpl.dylib, jpl.pl and jpl.jar from some version and dump it into another with quite a wide variety of versions as both the C API of Prolog and Java are pretty stable. As your student describes, notably on the Mac you have to do some fiddling with the link paths though. On Windows, just make sure the dll and exe are all in the same dir. On Linux it will typically also wok out of the box.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment