menu
an API between SWI-Prolog and the Java Virtual Machine - hosted on GitHub

Deploying for users - on Linux

To use JPL under Linux one must have the following in place (here showing the locations under Linux Mint distribution under packages swi-prolog-nox and swi-prolog-java):

  • A SWIPL install containing the core SWI system, which includes:
    • A SWIPL home directory, located at /usr/lib/swi-prolog/ and containing the whole SWIPL core system, including a booting .prc file (e.g., boot.prc).
    • The C Native core SWIPL library /usr/lib/swi-prolog/lib/x86_64-linux/libswipl.so.
    • The set of C Native SWIPL libraries for each package (files .so), located in /usr/lib/swi-prolog/lib/x86_64-linux/
  • The JPL package, which includes:
    • The C Native JPL Library libjpl.so at $SWI_HOME_DIR/lib/x86_64-linux/libjpl.so.
    • The Java API JAR file jpl.jar in $SWI_HOME_DIR/lib/jpl.jar.
    • The Prolog API as an SWIPL source module jpl.pl at $SWI_HOME_DIR/library.

What does an embedded application need to find?

  • The Java API via jpl.jar. This needs to be in the CLASSPATH.
  • All Prolog .pl core libraries, including jpl.pl. These are found relative to SWIPL’s home: $SWI_HOME_DIR/library
  • All C Native libraries .so, including libjpl.so. For that, LD_LIBRARY_PATH needs to be given.
  • If doing Prolog-calls-Java, libjvm.so’s directory needs to be in LD_LIBRARY_PATH for the JVM shared objects to be found.

Which SWIPL version to (not) use?

JPL is generally distributed with official Linux. For example, in Ubuntu-based systems, JPL is provided via package swi-prolog-java. That package includes the C library libjpl.so, the Java API jpl.jar, the Prolog module jpl.pl as well as all associated documentation. However, these distribution-based packages are highly out-of-date. There are two solutions to get more up to date SWIPL:

  1. For Debian-based systems (Debian, Ubuntu, Mint, …) you can get the latest stable and development versions via this PPAs provided directly by SWI-Prolog.
    • As of June 2020, it has 8.2.0 and JPL 7.6.0.
  2. Manually compile & install from sources at SWI-devel repo using CMAKE. See instructions below.

If you want to have more than one SWIPL installed (your locally compiled system and the distribution one), you may want to use fnogatz’s swivm to manage them.

Configuring environment variables

When embedding SWIPL into a Java, one may need to “tell” the Java application the right information, via environment variables, so that SWIPL is initialized properly and can find all resources (.pl and .so libraries).

In general, if the Java application will use the default executable of the system (i.e., the one that runs when executing swipl), then you only need to set-up CLASSPATH to include jpl.jar and possibly LD_PRELOAD to point to your active SWIPL libswipl.so library to avoid run-time errors. The executable has a pointer to the right information to initialize; see here.

However, if your embedded application must use an SWIPL & JPL version that is not the executable default in the system, one needs to provide the right paths to find SWIPL’s home dir and SWIPL’s C native .so libraries.

Using stable distribution versions of SWIPL

To use the SWIPL install in the standard distribution install location:

SWI_HOME_DIR=/usr/lib/swi-prolog/   # if default binary not pointing to this version
LD_LIBRARY_PATH=/usr/lib/swi-prolog/lib/x86_64-linux/   # to find all .so, including libjpl.so
CLASSPATH=/usr/lib/swi-prolog/lib/jpl.jar # Java API
LD_PRELOAD=/usr/lib/libswipl.so  # core SWIPL

Using locally compiled and installed version of SWIPL

Alternatively, if you have compiled and installed an SWIPL system, say, under directory /usr/local/swipl-git/, then:

SWI_HOME_DIR=/usr/local/swipl-git/lib/swipl/  # if binary exec not pointing to this SWIPL
LD_LIBRARY_PATH=/usr/local/swipl-git/lib/swipl/lib/x86_64-linux/     # to find all .so, including libjpl.so
CLASSPATH=/usr/local/swipl-git/lib/swipl/lib/jpl.jar
LD_PRELOAD=/usr/local/swipl-git/lib/swipl/lib/x86_64-linux/libswipl.so  # see below for explanation

or in one line (for IDE Run configurations, for example):

CLASSPATH=/usr/local/swipl-git/lib/swipl/lib/jpl.jar;LD_LIBRARY_PATH=/usr/local/swipl-git/lib/swipl/lib/x86_64-linux/;LD_PRELOAD=/usr/local/swipl-git/lib/swipl/lib/x86_64-linux/libswipl.so;SWI_HOME_DIR=/usr/local/swipl-git/lib/swipl/

If you want to run your application against a development source tree of SWIPL & JPL that is not yet installed in the system, then refer to Developing JPL guide.

Again, you can check fnogatz’s swivm system to manage many SWIPL.

Troubleshooting

Cannot find libjvm.so (Prolog-calls-Java)

When loading JPL module in Prolog (Prolog-calls-Java):

?- use_module(library(jpl)).
ERROR: /usr/lib/swi-prolog/library/jpl.pl:4243:
	'$open_shared_object'/3: libjvm.so: cannot open shared object file: No such file or directory
ERROR: /usr/lib/swi-prolog/library/jpl.pl:4243:
	/usr/lib/swi-prolog/library/jpl.pl:4243: Initialization goal raised exception:
	library `java' does not exist (Please add directory holding libjava.so to $LD_LIBRARY_PATH)
ERROR: Exported procedure jpl:jpl_c_lib_version/1 is not defined
true.

Do a locate libjvm.so to find where it is and add the path to LD_LIBRARY_PATH so that Java VM shard objects can be found:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/jvm/java-11-openjdk-amd64/lib/server

For Java Oracle: /usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/

FATAL ERROR: Could not find system resources

System is unable to find the SWI Prolog framework, including failing to find library libswipl.so. See here

Make sure LD_LIBRARY_PATH and SWI_HOME_DIR are correctly set (see above).

Run-time error: process.so: undefined symbol: Sfilefunctions

You need to tell the system to pre-load SWI main library:

export LD_PRELOAD=/home/ssardina/git/soft/prolog/swipl-devel.git/build/src/libswipl.so

Check this post and what is preloading?

Error “undefined symbol: PL_new_atom” when reading files #10

Check this post.

This is resolved by pre-loading libswipl.so via LD_PRELOAD as above.

ERROR source_sink `jar(‘jpl.jar’)’ does not exist

Some Prolog file is not able to find jpl.jar that it needs to call some class. We need to setup CLASSPATH to point to jpl.jar to be used.