3

How can I run a clojure script from matlab?

I tried following: run matlab with jdk 1.7 and then call java

MATLAB_JAVA=/usr/lib/jvm/java-7-oracle/jre matlab

in the matlab, set classpath and use clojure compiler

javaaddpath([pwd '/lib/clojure-1.5.1.jar'])
import clojure.lang.RT

Here I got error:

Error using import
Import argument 'clojure.lang.RT' cannot be found or cannot be imported. 

When I writing java class that runs clojure, everything working from console, but whould not run from matlab. please advice.

Amro
  • 123,847
  • 25
  • 243
  • 454
  • From what I remember, Matlab will have problems if you want to use classes or java packages compiled using different java version that the one which is included with Matlab (i.e. 1.6). – Marcin Oct 27 '13 at 23:49
  • That's why he's using MATLAB_JAVA, i guess. This should make matlab use the jvm pointed to, rather than the one included in MATLAB. And, since this appears to be on a linux-system: MATLAB only brings its own jre on windows, afaik. – sebastian Oct 28 '13 at 09:11
  • 1
    Since you say you want to run a script, rather than call Clojure functions or something like that, couldn't you do it with `system`? – Rörd Oct 28 '13 at 20:37
  • That is workaround that I did. Run clojure in separated process using system and saved result as java object in temp file. Then from matlab read this file. ugly, but working. –  Oct 29 '13 at 23:37
  • What OS, OS version, and Matlab version are you running? – Andrew Janke Mar 20 '14 at 03:55

1 Answers1

6

It looks like this is a problem with Clojure not being happy running from Matlab's "dynamic classpath". I got the same error with Matlab R2014a on OS X 10.9, using either the bundled JVM or Java 1.7.0u51. But if I add clojure-1.5.1.jar to the static classpath by putting it in a custom javaclasspath.txt in the Matlab startup directory, then the Clojure classes become visible.

>> version -java
ans =
Java 1.7.0_51-b13 with Oracle Corporation Java HotSpot(TM) 64-Bit Server VM mixed mode
>> cloj = clojure.lang.RT
cloj =
clojure.lang.RT@77de6590

Hacking the Java classpath

You use the "class path hacking" approach in this answer to add entries to the static classpath from the Matlab command line and not have to muck around with a custom Matlab setup. The answer there involves writing a new Java class, but you can do the equivalent in pure M-code.

function javaaddpathstatic(file)
%JAVAADDPATHSTATIC Add an entry to the static classpath at run time
%
% javaaddpathstatic(file)
%
% Adds the given file to the STATIC classpath. This is in contrast to the
% regular javaaddpath, which adds a file to the dynamic classpath.
%
% Files added to the path will not show up in the output of
% javaclasspath(), but they will still actually be on there, and classes
% from it will be picked up.
%
% Caveats:
% * This is a HACK and bound to be unsupported.
% * You need to call this before attempting to reference any class in it,
%   or Matlab may "remember" that the symbols could not be resolved.
% * There is no way to remove the new path entry once it is added.

parms = javaArray('java.lang.Class', 1);
parms(1) = java.lang.Class.forName('java.net.URL');
loaderClass = java.lang.Class.forName('java.net.URLClassLoader');
addUrlMeth = loaderClass.getDeclaredMethod('addURL', parms);
addUrlMeth.setAccessible(1);

sysClassLoader = java.lang.ClassLoader.getSystemClassLoader();

argArray = javaArray('java.lang.Object', 1);
jFile = java.io.File(file);
argArray(1) = jFile.toURI().toURL();
addUrlMeth.invoke(sysClassLoader, argArray);

So, use this javaaddpathstatic() instead of javaaddpath() and your code might work.

Community
  • 1
  • 1
Andrew Janke
  • 23,508
  • 5
  • 56
  • 85