0

After installing SWI-Prolog in my computer, I went on to try one of its examples, and found out this particular beauty:

run:
Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Program Files (x86)\swipl\bin\jpl.dll: Can't find dependent libraries
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1807)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1732)
    at java.lang.Runtime.loadLibrary0(Runtime.java:823)
    at java.lang.System.loadLibrary(System.java:1028)
    at jpl.JPL.loadNativeLibrary(JPL.java:100)
    at jpl.fli.Prolog.<clinit>(Prolog.java:85)
    at jpl.Query.open(Query.java:286)
    at jpl.Util.textToTerm(Util.java:162)
    at jpl.Query.<init>(Query.java:198)
    at main.ProjetoPLP.main(ProjetoPLP.java:12)
Java Result: 1

I've checked, and there is a jpl.dll file inside the aforementioned folder, so I'm not exactly sure what's going on here. I've checked older questions on this website, and the internets, but neither provided any sort of conclusive answer.

Anyone has any idea how to go about this?

EDIT:

Here is the code I'm trying to run, in case that helps.

package main;
import java.io.*;
import java.util.Hashtable;
import jpl.Query;
import org.apache.commons.io.*;

public class ProjetoPLP
{

    private static void loadJPLDll() {
    try {
        InputStream in = ProjetoPLP.class.getResourceAsStream("/test/resources/jpl.dll");
        File fileOut = new File("jpl.dll");
        OutputStream out = FileUtils.openOutputStream(fileOut);
        IOUtils.copy(in, out);
        in.close();
        out.close();
        System.load(fileOut.getAbsolutePath());// loading goes here
    } catch (Exception e) {
        e.printStackTrace();
    }
}
    public static void
    main(String args[] )
    {

                loadJPLDll();
        String t1 = "consult('family.pl')";
        Query q1 = new Query(t1);

        System.out.println( t1 + " " + (q1.hasSolution() ? "succeeded" : "failed") );

        //--------------------------------------------------

        String t2 = "child_of(joe, ralf)";
        Query q2 = new Query(t2);

        System.out.println( t2 + " is " + (q2.hasSolution() ? "provable" : "not provable") );

        //--------------------------------------------------

        String t3 = "descendent_of(steve, ralf)";
        Query q3 = new Query(t3);

        System.out.println( t3 + " is " +(q3.hasSolution() ? "provable" : "not provable") );

        //--------------------------------------------------

        String t4 = "descendent_of(X, ralf)";
        Query q4 = new Query(t4);

        System.out.println( "first solution of " + t4 + ": X = " + q4.oneSolution().get("X"));

        //--------------------------------------------------

        Hashtable[] ss4 = q4.allSolutions();

        System.out.println( "all solutions of " + t4);
        for ( int i=0 ; i<ss4.length ; i++ ) {
            System.out.println( "X = " + ss4[i].get("X"));
        }

        //--------------------------------------------------

        System.out.println( "each solution of " + t4);
        while ( q4.hasMoreSolutions() ){
            java.util.Hashtable s4 = q4.nextSolution();
            System.out.println( "X = " + s4.get("X"));
        }

        //--------------------------------------------------

        String t5 = "descendent_of(X,Y)";
        Query q5 = new Query(t5);

        System.out.println( "each solution of " + t5 );
        while ( q5.hasMoreSolutions() ){
            java.util.Hashtable s5 = q5.nextSolution();
            System.out.println( "X = " + s5.get("X") + ", Y = " + s5.get("Y"));
        }

    }

}

2 Answers2

0

Just for your information if you have a jar then it won't work.

 System.load("xxx.dll"); won't work inside the jar file.

It will need to a physical file.

What you can do is:

Create a package as "test.resources" and put your "jpl.dll" inside it.

Now inside your main method you can load the DLL as

private static void loadJPLDll() {
    try {
        InputStream in = YourCLASS.class.getResourceAsStream("/test/resources/jpl.dll");
        File fileOut = new File("jpl.dll");
        OutputStream out = FileUtils.openOutputStream(fileOut);
        IOUtils.copy(in, out);
        in.close();
        out.close();
        System.load(fileOut.getAbsolutePath());// loading goes here
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Remember to make this work you would need commons-io jar.

Makky
  • 17,117
  • 17
  • 63
  • 86
  • I don't understand one (or possibly more) things, why the use of the 'File fileOut = new File(name);'? Or, better, what should go in that name? 'jpl.dll', or something else entirely? – user2444503 Jun 04 '13 at 09:28
  • I've tried it, and it doesn't seem to work for me, as I'm till receiving the same exception. And yes, I do have the Apache Commons-io. – user2444503 Jun 04 '13 at 19:22
  • I have added the source code of what I'm trying to do in the original post. I'm more than a bit lost in this situation, since I haven't done anything like this in the past. – user2444503 Jun 04 '13 at 21:04
  • I tried myself I think you will end adding quite a lot of other dll files as jpl.dll depends on them. – Makky Jun 05 '13 at 07:47
  • So I should run an app that finds out which dependencies the .dll has and manually add them to my folders? I'll look into it... – user2444503 Jun 05 '13 at 11:19
  • It hasn't helped, I apologize. I've later discovered that the jpl.dll is a bit faulty, and requires inserting lots of other .dlls into the Java path. I'll be writing a conclusive answer to that soon. – user2444503 Jun 14 '13 at 06:12
0

For windows change the environment path settings and add C:\Program Files (x86)\swipl\bin if you have swi-prolog installed in that location. Alternatively the dll files can be loaded as shown below.

private static void loadDLL(String location) {
    try {
        File dll = new File(location);
        System.load(dll.getAbsolutePath());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    //load the dependent dll files
    loadDLL("libwinpthread-1.dll");
    loadDLL("libgcc_s_sjlj-1.dll");
    loadDLL("libgmp-10.dll");
    loadDLL("libswipl.dll");    
    loadDLL("json.dll");
    loadDLL("jpl.dll");

    //your code here
}

You will need to add the native library location for the attached JPL.jar file if using the above code. You can follow How to set the java.library.path from Eclipse

Community
  • 1
  • 1
Odessy
  • 1
  • 1