10
$\begingroup$

I'm trying to connect to a remote Mathematica 8 kernel (on a Windows machine) using J/Link. On the client machine, I put the JLinkNativeLibrary.dll file in C:\Documents and Settings\User\My Documents. But, it gives me the error message "cannot find the required native library named JLinkNativeLibrary".

Here is my code

public static void main(String[] args) {
        KernelLink link;
        try {
            String jLinkDir = "C:\\Documents and Settings\\User\\My Documents";
            System.setProperty("com.wolfram.jlink.libdir", jLinkDir);            
            link = MathLinkFactory.createKernelLink("-linkmode connect -linkprotocol tcpip -linkname [email protected]");
        } catch (MathLinkException ex) {
            ex.printStackTrace();
        }
    }

Exception :

Fatal error: cannot find the required native library named JLinkNativeLibrary. Exception in thread "main" java.lang.UnsatisfiedLinkError: com.wolfram.jlink.NativeLink.MLOpenString(Ljava/lang/String;[Ljava/lang/String;)J at com.wolfram.jlink.NativeLink.MLOpenString(Native Method) at com.wolfram.jlink.NativeLink.(NativeLink.java:117) at com.wolfram.jlink.MathLinkFactory.createMathLink0(MathLinkFactory.java:281) at com.wolfram.jlink.MathLinkFactory.createMathLink(MathLinkFactory.java:194) at com.wolfram.jlink.MathLinkFactory.createKernelLink0(MathLinkFactory.java:171) at com.wolfram.jlink.MathLinkFactory.createKernelLink(MathLinkFactory.java:65) at mathematica.Sample.main(Sample.java:21)

I also wrote the following code where KernelLink gets created but there is some problem with establishing the connection. It gives an error "MathLinkException: 1: MathLink connection was lost."

public static void main(String[] args) {
        KernelLink ml = null;
        try {
            ml = MathLinkFactory.createKernelLink("-linkmode connect -linkprotocol tcp -linkname [email protected]");
        } catch (MathLinkException ex) {
            Logger.getLogger(MathematicaSample.class.getName()).log(Level.SEVERE, null, ex);
            return;
        }
        try {
            ml.connect(1000000); // Wait at most 10 seconds
        } catch (MathLinkException e) {
            // If the timeout expires, a MathLinkException will be thrown.
            e.printStackTrace();
            ml.close();
            return; // Or whatever is appropriate.
        }    
        try {
            // Get rid of the initial InputNamePacket the kernel will send
            // when it is launched.
            ml.discardAnswer();
            ml.evaluate("<<MyPackage.m");
            ml.discardAnswer();
            ml.evaluate("2+2");
            ml.waitForAnswer();
            int result = ml.getInteger();
            System.out.println("2 + 2 = " + result);            
        } catch (MathLinkException e) {
            System.out.println("MathLinkException occurred: " + e.getMessage());
        } finally {
            ml.close();
        }
    }
}

Does anyone know how to connect to the kernel?

$\endgroup$
3
  • $\begingroup$ Window->Preferences->Java->Installed JREs. Then choose your current JRE(JDK) or the one you are using and click Edit. Fill Default VM Arguments: -Djava.library.path="the pathhhh of dll" or Under Linux set LD_LIBRARY_PATH. Under Windows set PATH. $\endgroup$
    – s.s.o
    Commented Nov 23, 2012 at 12:09
  • $\begingroup$ @s.s.o Why don't you give that as an official answer? $\endgroup$ Commented Nov 23, 2012 at 23:05
  • $\begingroup$ @ Sjoerd C. de Vries I was not sure if it could help. $\endgroup$
    – s.s.o
    Commented Nov 24, 2012 at 0:39

4 Answers 4

15
$\begingroup$

What you did with setting the "com.wolfram.jlink.libdir" property will work. Perhaps you didn't enter the correct path, or you used the wrong JLinkNativeLibrary.dll file (meaning you used the 32-bit one from JLink/SystemFiles/Libraries/Windows, instead of the 64-bit one from JLink/SystemFiles/Libraries/Windows-x86-64, or vice-versa).

But you really shouldn't bother with that at all. J/Link is set up to automatically find its own correct native library based on the library's location relative to JLink.jar. You probably copied JLink.jar somewhere out of the J/Link layout, and then copied JLinkNativeLibrary.dll somewhere else. I recommend that you leave J/Link together as a unit, and simply point your Java class path at the J/Link that is in the Mathematica layout. You can do this in the usual way, either by setting the CLASSPATH environment variable to include the path to JLink.jar, or by using the -classpath option when launching Java. If you do this, then J/Link will always find its native library, no matter what platform you are on.

Having said that, if you still want to copy parts of J/Link out of its layout and use them from a different location (you might want to do this if you are distributing a program that uses J/Link), then your com.wolfram.jlink.libdir trick will work. It will also work to simply put JLinkNativeLibrary.dll alongside JLink.jar. Even better, put a SystemFiles/Libraries directory hierarchy alongside JLink.jar. In other words:

    mydir/
        MyClass.class
        JLink.jar
        SystemFiles/
            Libraries/
                Windows/
                    JLinkNativeLibrary.dll
                Windows-x86-64/
                    JLinkNativeLibrary.dll
                Linux/
                    libJLinkNativeLibrary.so
                ... etc. for other systems

This lets you include libraries for multiple different systems. You don't need to do anything special for all this to work--just make sure the class path points at JLink.jar.

As for your second problem, your program will work correctly as written (one caveat: use 'tcpip' as the protocol, not the ancient 'tcp'), but it requires some cooperation from the program on the other side of the link. If you do nothing but launch your program, it will attempt to connect a link on the port 1234, but this will fail with the MathLink exception you showed, because there is no program on the other side that has established a "listen" link on that port. Try the following sequence of steps, and you should find that the program works as expected:

  1. Launch the Mathematica kernel on the remote machine.
  2. In that kernel, create a listening link on the desired port and make it the $ParentLink:

    $ParentLink = LinkCreate["1234", LinkProtocol->"TCPIP"]
    
  3. On the Windows client machine, launch your Java program. It will connect to the listening kernel, print the 2+2 computation and exit.

If you are trying to launch the kernel on the remote Windows machine automatically from your Java program, that is a different matter that is beyond the scope of this answer.

$\endgroup$
5
  • $\begingroup$ Thanks for the answer! Great to have you with us! $\endgroup$ Commented Nov 26, 2012 at 10:00
  • $\begingroup$ Hi Todd, nice to see you here! +1. $\endgroup$ Commented Nov 26, 2012 at 13:37
  • $\begingroup$ Good to be here. Leonid has been doing a fine job of recruiting folks into this group! $\endgroup$ Commented Nov 26, 2012 at 22:30
  • $\begingroup$ Thanks Todd. Your answer is really helpful. Actually, I'm trying to launch the kernel on the remote Windows machine automatically from the Java program. can you suggest me how to achieve this. $\endgroup$ Commented Nov 27, 2012 at 3:31
  • $\begingroup$ It can be a bit conplex, as I recall, and I never do it, so I'm no expert. I think this would best be posted as a new, separate question. One that specifically mentions launching a remote Windows kernel via MathLink or JLink. Other users here will probably have information at least as good as what I can give. $\endgroup$ Commented Nov 27, 2012 at 16:52
3
$\begingroup$

you can try to add the dll to your path list.

  • Window->Preferences->Java->Installed JREs. Then choose your current JRE(JDK) or the one you are using and click Edit. Fill Default VM Arguments: -Djava.library.path="the pathhhh of dll"
  • or Under Linux set LD_LIBRARY_PATH. Under Windows set PATH.
$\endgroup$
1
$\begingroup$

As referred in https://stackoverflow.com/questions/30005679/java-jboss-fatal-error-cannot-find-the-required-native-library-named-jlinknativ

Make sure the directory with DLLs can be seen by Java: https://www.chilkatsoft.com/java-loadLibrary-Windows.asp

it worked for me!

$\endgroup$
0
$\begingroup$

You can try setting the system property from the Java code with the following:

nativePath = "/Applications/Mathematica.app/SystemFiles/Links/JLink/SystemFiles/Libraries/MacOSX-x86-64/";

System.setProperty("java.library.path",nativePath);

Make sure you use the mathching version of JLink native library and JRE. On some systems such as Mac OS X the JRE may work in the x64 mode by default. You can experiment with setting the execution mode with the -d32(-d64) options.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.