Skip to content
ssardina edited this page Nov 1, 2020 · 30 revisions

JPL - Java <-> SWI Prolog Interface

JPL is a set of Java classes and C functions providing a bidirectional interface between Java and Prolog. JPL uses the Java Native Interface (JNI) to connect to a Prolog engine through the Prolog Foreign Language Interface (FLI). JPL is not a pure Java implementation of Prolog; it makes extensive use of native implementations of Prolog on supported platforms.

This is the projct Wiki with information to support development of JPL. This Wiki may provide more information than the basic one in documentation Developing JPL.

For understanding JPL and using it in your embedded application please refer to JPL Documentation page.

For development of JPL, we follow The GitHub Standard Fork & Pull Request Workflow.

Packages and libraries needed

First, let us make sure we have all the necessary libraries and tools to compile the system:

sudo apt-get install \
        build-essential autoconf curl chrpath pkg-config \
        ncurses-dev libreadline-dev libedit-dev \
        libunwind-dev \
        libgmp-dev \
        libssl-dev \
        unixodbc-dev \
        zlib1g-dev libarchive-dev \
        libossp-uuid-dev \
        libxext-dev libice-dev  libxinerama-dev libxft-dev \
        libxt-dev libxpm-dev  libjpeg-dev \
        libdb-dev \
        libpcre3-dev \
        libyaml-dev \
        openjdk-11-jdk junit \
        make ninja-build \
        cmake

Since we want to get JPL it is mandatory to have:

  • openjdk-11-jdk or any package that can provide java and the compiler javac. (Run javac -version to test).
  • junit, for running Java unit testing.

As explained in fnogatz's swivm repo, if you want to reduce resources, the following packages are optional:

  • libreadline-dev and libedit-devl: Without, you do not have history feature in SWIPL interpreter.
  • unixodbc-dev: Without, you have no ODBC database connectivity (e.g., MySQL)
  • libssl-dev: Without, you have no SSL (and HTTPS) support.
  • libgmp-dev: Without, you lack unbounded integer support, rational numbers, good random number generators, etc.
  • libarchive-dev: Without, you can not unpack and install add-ons.
  • libpcre3-dev: Without, you have no regular expression support (library(pcre)).
  • libyaml-dev: Without, you have no YAML support (library(yaml)).
  • libxt-dev, libxpm-dev, libjpeg-dev (and maybe others) are needed for xpce.

Environment Variables

There are several environmnet variables that play some role in running SWIPL with JPL:

  • SWI_HOME_DIR: to find the root dir of SWIPL install to be used.
  • LD_LIBRARY_PATH (dynamic linker search path):
    • to find native libraries, including libjpl.so and libswipl.so;
    • to find the JVM shared objects (libjvm.so) when calling Java from Prolog, as explained here.
  • CLASSPATH: to find the jpl.jar file implementing the JPL Java API.
  • LD_PRELOAD: to pre-load certain libraries (e.g., libswipl.so).
  • JAVA_HOME: to find the Java compiler and JNI when compiling JPL.

Find more information on ach in JPL doc here.

Set-up devel repository (first time)

Here is a run on cloning, configuring, compiling, testing, and installing:

git clone https://github.com/SWI-Prolog/swipl-devel.git
cd swipl-devel
git submodule update --init

# Avoid conflicts with existing SWI installs (e.g., Ubuntu distribution)
unset LD_LIBRARY_PATH LD_PRELOAD SWI_HOME_DIR   

mkdir build
cd build

# via make
cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local/swipl-git -DINSTALL_DOCUMENTATION=OFF -DINSTALL_TESTS=ON ..
make -j 8

# via ninja  (faster)
cmake -G Ninja -DCMAKE_INSTALL_PREFIX:PATH=/usr/local/swipl-git -DINSTALL_DOCUMENTATION=OFF -DINSTALL_TESTS=ON ..
ninja

ctest -j 8 # run all tests (-j makes it faster!)

sudo make install 
/usr/local/swipl-git/bin/swipl

Notes:

  • The -DINSTALL_TESTS=ON will install the test cases to test the system in the deployment environment.. In the case of JPL, this will only install the Prolog-calls-Java tests.
    • Once installed, tests can be run via goal ? - test_installation.
  • The unset step is important if you have a distribution version installed in the system. See this issue if you get Could not find system resources FATAL ERROR.
  • If there are other versions installed (e.g., distribution version) you need to make sure you are running the one you want; and you may need to setup SWI_HOME_DIR and LD_LIBRARY_PATH if the Prolog is embedded into C/Java so that the right version is used. See discussion above on how to keep many SWI versions and how to use these environment variables.
  • SWI provides a script to activate the current install under the build/ dir of CMAKE or the local install. Please refer to script ../scripts/swipl-activate in the CMAKE documentation of SWI.
    • Note this will create three swipl symbolic links in $HOME/bin that you would need to delete if you want to use another install (e.g., the distribution one). So may not be the best way to work on, I prefer to work with the Linux alternative framework as described above.

Run "live" un-installed SWIPL

We can run the compiled but uninstall SWIPL system as follows.

Suppose that env variable SWI_BULD points to the dir where SWIPL was compiled via CMAKE, for example:

$ echo $SWI_BUILD 
/home/ssardina/git/soft/prolog/swipl-devel.git/build/

So we can now run it as folows by setting the boot file via -x and the SWIPL root dir with --home:

$ $SWI_BUILD/src/swipl -x $SWI_BUILD/home/boot.prc -F swipl --home=$SWI_BUILD/home 

Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.1-34-g9adbe8ff1-DIRTY)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

    CMake built from "/home/ssardina/git/soft/prolog/swipl-devel.git/build"

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

Another possibility is to set the boot file and root folder by setting environment variables SWI_HOME_DIR and SWIPL_BOOT_FILE that SWIPL will understand.

So, from build/ directory (where CMAKE compiled SWIPL):

/usr/bin/env "SWI_HOME_DIR=home" "SWIPL_BOOT_FILE=home/boot.prc"  src/swipl

Special tags in commits for changelog

Start relevant commits with [A-Z]+: such that they become entries in the changelog.

The frequent tags are FIXED, ADDED and MODIFIED, but anything matching the regex above is copied to the changelog.

For example, "ADDED: Rational number support".

Developing JPL within an IDE

It is usually convenient to develop the Java side of JPL within and IDE. As an example, we will be using IntelliJ, but the same ideas should apply for other IDEs (e.g., ECLIPSE).

The project in the IDE will be under <swi-devel>/package/jpl which is "outside" of the binary generated by CMAKE under <swi-devel>/build.

As of May 2020, the JPL is a Maven project, so this already simplifies many things. However, one still needs to do a few things to make sure the Java being developed accesses the correct SWI development under the CMAKE binary dir <swi-devel>/build, including the compiled libjpl.so library.

So, to run, for example, unit testing classes for Java-calls-Prolog within the IDE:

  1. Compile SWI-Prolog using CMAKE, to compile not only SWI itself but also the C code of JPL <swi-devel>/project/jpl/src/c/jpl.c which will yield library <swi-devel>/build/packages/jpl/libjpl.so.

  2. Create a JUnit Run on some of the testing classes, like org.jpl7.junit.Test_Atom.

  3. Edit the working directory of the JUnit Run created to be <swi-devel>/packages/jpl.

    • Note this is the source code dir of JPL, not the folder within the build/ directory used in step 1.
  4. Edit the environment variables of the JUnit Run created to make sure it is using the current development of SWIPL compiled in step 1::

     ```bash
     LD_LIBRARY_PATH=../../build/packages/jpl;
     SWI_HOME_DIR=../../build/home;
     SWIPL_BOOT_FILE=../../build/home/boot.prc;
     LD_PRELOAD=../../build/src/libswipl.so 
     ```
    

Notes:

  • The LD_PRELOAD variable should not be necessary for the tests.
  • If the tests includes some Prolog code using some Java class in the JPL Java API, then one will need to setup an artifact to produce jpl.jar file, say the target dir for the project is out/ and also modify the CLASSPATH environment variable in the runner. This is needed because some Prolog test files will look for Java classes in that JAR and you want to use the one being developed within the IDE rather than the last generated by CMAKE (which could be old and don't reflect the changes did inside the IDE yet).
  • To get all the warnings add -Xlint to the "Additional commands line parameters" to the Java Compiler (Settings / Build / Compiler / Java Compiler). Check javac options.

Common commands from build/

cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local/swipl-git -DINSTALL_DOCUMENTATION=OFF ..

make -C packages/jpl clean  ; make -j 8

ctest -V  -R jpl:prolog_in_java

src/swipl -x home/boot.prc -f none --home=home/ --no-signals

LICENSE

JPL is released under the terms of the Simplified BSD License. See LICENSE file.