I have got a Matlab code which at last calculates a vector of indexes. I used library compiler in order to compile matlab code to a java package .jar file. I exported the jar file in order to run it for my main Java project. The name of the package class is Epidemic. I imported the jar file (add it as an external jar). In main code I tried to create an object of my class (in jar file). I have already defined the name of the class as Epidemic. Thus, my code:
import epidemic.Epidemic;
...
public static void main(String[] args) throws IOException {
List<Double> list1 = new ArrayList<Double>();
List<Double> list2 = new ArrayList<Double>();
Epidemic object = new Epidemic();
object.epidemic(list1, list2);
System.out.println(list1);
}
I add the .jar file to java project using project->Libraries right click add external jars. Netbeans automatically detects object's methods. However I am getting the following errors:
Exception in thread "main" java.lang.NoClassDefFoundError:
com/mathworks/toolbox/javabuilder/internal/MWComponentInstance
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:367)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at twittertrendsetters.TwitterTrendSetters.main(TwitterTrendSetters.java:70)
Caused by: java.lang.ClassNotFoundException:
com.mathworks.toolbox.javabuilder.internal.MWComponentInstance
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 13 more
What is the issue here? Am I supposed to add something else in order the jar to work properly?
EDIT: I add the .jar file located in MATLABROOT/toolbox/javabuild/jar/javabuild.jar to my classpath and the class it seems to work. Now I am facing another problem. When I print the list1 which based on html docs takes the output of matlab .m file I got an empty arrayList. Matlab function returns an array Nx1 of doubles. How can I parse it correctly to the java arrayList.
My matlab code:
function eP = epidemic() // zero input
graph = dlmread('graph.edges'); //a graph
graph_ids=importdata('cms_V3_id.txt'); // indexes of the graph
for index = 1:length(graph)
grph(index,1) = find(graph_ids == graph(index,1));
grph(index,2) = find(graph_ids == graph(index,2));
end
grph(:,3)= graph(:,3);
grph(end + 1, :, :) = [max(max(grph)) max(max(grph)) 1 ];
grph = spconvert(grph);
[S, prev] = brutte_topk2(grph, 3707); //function approximate pagerank result
eP = graph_ids(S); // returning a list of indexes
I tried to use your approach. I create a table of OBject and parse the result into it.
Epidemic object = new Epidemic();
Object[] result;
result = object.epidemic(1);
System.out.println((Double)result[0]);
However I am getting javabuilder.MWNumericArray cannot be cast to java.lang.Double. When I print just the reuslt
There are two things you need to add to the Java project classpath:
$MATLABROOT\toolbox\javabuilder\jar\javabuilder.jar
, otherwise install the appropriate MCR runtime (available for free), and locate the JAR file in a similar path.See here for the full instructions.
For the sake of completeness, below is a working example.
Assume we have the following MATLAB function that returns a array of numbers.
function list = epidemic()
list = randi(100, [1, 10]);
end
Using the applicationCompiler
MATLAB app, create a new project to build a "Java Package". Add the above function to the project, set class and method names, then build the package. We should get a JAR file, say: Epidemic.jar
Next we create a Java program to test the above package. For example:
import java.util.*;
import com.mathworks.toolbox.javabuilder.*; // MATLAB Java Builder
import Epidemic.*; // our compiled package
public class TestEpidemic {
public double[] getArray() throws MWException {
Epidemic obj = null;
Object[] out = null;
double [] arr = null;
try {
obj = new Epidemic();
out = obj.epidemic(1); // request one output
arr = (double[]) ((MWArray)out[0]).getData();
} catch (MWException e) {
System.out.println("Exception: " + e.toString());
} finally {
MWArray.disposeArray(out);
obj.dispose();
}
return arr;
}
public static void main (String[] args) {
try {
TestEpidemic e = new TestEpidemic();
double[] arr = e.getArray();
for(double x : arr) {
System.out.println(x);
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}
Finally we compile and run the test program:
javac.exe -classpath "%MATLABROOT%\toolbox\javabuilder\jar\javabuilder.jar";.\Epidemic.jar TestEpidemic.java
java.exe -classpath .;"%MATLABROOT%\toolbox\javabuilder\jar\javabuilder.jar";.\Epidemic.jar TestEpidemic
you should see an array of 10 double numbers printed.
A JAR file can only return an exit code if it contains a main method. The type of the return value is an integer. You can achieve this if you use System.exit(returnCode)
.
If you mean that you have another project in which you want to embedd this project, you have to get rid of the right dependencies and just call the method from the JAR you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With