Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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 8080@172.20.48.113");
        } 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 1234@172.20.48.113");
        } 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?

share|improve this question
    
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. –  s.s.o Nov 23 '12 at 12:09
    
@s.s.o Why don't you give that as an official answer? –  Sjoerd C. de Vries Nov 23 '12 at 23:05
    
@ Sjoerd C. de Vries I was not sure if it could help. –  s.s.o Nov 24 '12 at 0:39
add comment

2 Answers

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.

share|improve this answer
    
Thanks for the answer! Great to have you with us! –  Oleksandr R. Nov 26 '12 at 10:00
    
Hi Todd, nice to see you here! +1. –  Leonid Shifrin Nov 26 '12 at 13:37
    
Good to be here. Leonid has been doing a fine job of recruiting folks into this group! –  Todd Gayley Nov 26 '12 at 22:30
    
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. –  user1832237 Nov 27 '12 at 3:31
    
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. –  Todd Gayley Nov 27 '12 at 16:52
add comment

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.
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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