Возвращаемое значение из файла jar, созданного из Matlab

У меня есть код Matlab, который, наконец, вычисляет вектор индексов. Я использовал компилятор библиотеки для компиляции кода matlab в java-пакет .jar файл. Я экспортировал файл jar, чтобы запустить его для моего основного проекта Java. Название класса пакета - это эпидемия. Я импортировал файл jar (добавьте его как внешнюю банку). В основном коде я попытался создать объект своего класса (в файле jar). Я уже определил название класса как Эпидемия. Таким образом, мой код:

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);
}

Я добавляю файл .jar в проект java, используя project- > Libraries, правой кнопкой мыши добавьте внешние банки. Netbeans автоматически обнаруживает методы объекта. Однако я получаю следующие ошибки:

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

В чем проблема? Должен ли я добавить что-то еще, чтобы баночка работала должным образом?

EDIT: я добавляю файл .jar, расположенный в MATLABROOT/toolbox/javabuild/jar/javabuild.jar, в мой путь к классам и класс, который, похоже, работает. Теперь я столкнулся с другой проблемой. Когда я печатаю список1, который на основе html docs принимает вывод файла matlab.m, я получил пустой массив. Функция Matlab возвращает массив Nx1 удвоений. Как правильно разобрать его в java-массиве.

Мой код matlab:

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

Я попытался использовать ваш подход. Я создаю таблицу OBject и анализирую результат.

    Epidemic object = new Epidemic(); 
    Object[] result;
    result = object.epidemic(1);
    System.out.println((Double)result[0]);

Однако я получаю javabuilder.MWNumericArray не может быть добавлен в java.lang.Double. Когда я печатаю только повтор

Ответ 1

Есть две вещи, которые нужно добавить в путь к классам Java:

  • развернутый JAR файл, который вы создали из кода MATLAB.
  • Java Builder собственные файлы JAR. Если на целевом компьютере установлен MATLAB, вы можете найти те, что находятся внутри $MATLABROOT\toolbox\javabuilder\jar\javabuilder.jar, в противном случае установите соответствующую MCR рабочую среду (доступно бесплатно) и найдите JAR файл аналогичным путем.

Подробнее см. здесь.


EDIT:

Для полноты ниже приведен рабочий пример.

  • Предположим, что мы имеем следующую функцию MATLAB, которая возвращает массив чисел.

    epidemic.m

    function list = epidemic()
        list = randi(100, [1, 10]);
    end
    
  • Используя приложение applicationCompiler MATLAB, создайте новый проект для создания "Java-пакета". Добавьте вышеприведенную функцию в проект, задайте имена классов и методов, затем создайте пакет. Мы должны получить JAR файл, скажем: Epidemic.jar

  • Далее мы создаем программу Java для тестирования вышеуказанного пакета. Например:

    TestEpidemic.java

    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();
            }
        }
    }
    
  • Наконец, мы скомпилируем и запустим тестовую программу:

    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
    

    вы должны увидеть массив из 10 двойных чисел, напечатанных.

Ответ 2

Файл JAR может возвращать только код выхода, если он содержит основной метод. Тип возвращаемого значения является целым числом. Вы можете достичь этого, если используете System.exit(returnCode).

Если вы имеете в виду, что у вас есть другой проект, в который вы хотите встроить этот проект, вам нужно избавиться от правильных зависимостей и просто вызвать метод из JAR, который вам нужен.