Matlab не может видеть некоторые из моих классов Java (не все) в пакете jar - PullRequest
11 голосов
/ 14 декабря 2011

У меня есть проблема, которая сводит меня с ума.Matlab видит только некоторые из моих классов, встроенных в JAR-файл

Если я скомпилирую классы вне пакета и добавлю путь к классу в Matlab с помощью javaaddpath, у меня не возникнет никаких проблем

Когда я компилирую класс в пакете, а затем пытаюсь получить к ним доступ в Matlab, у меня возникают проблемы.Ниже кода Matlab

>>javaaddpath('/Users/me/Documents/workspace/EKGTest.jar');
>>clear java
>>import com.neurosky.thinkgear.*
>>methods('EkgSense')

Methods for class com.neurosky.thinkgear.EkgSense:

EkgSense                  getClass                  notify                    reset            
addTemplate               getClassificationResults  notifyAll                  toString
equals                    hashCode                  processData               wait   

>>methods('EkgEpoch')

No methods for class EkgEpoch or no class EkgEpoch

Теперь я смотрю в пакете, все классы являются открытыми.Это результат jar -tf

osx:/Users/me/Documents/workspace> jar tf EKGTest.jar
META-INF/MANIFEST.MF
META-INF/REFACTORINGS.XML
com/
com/neurosky/
com/neurosky/thinkgear/
com/neurosky/thinkgear/EkgEpoch.class
com/neurosky/thinkgear/EkgEpoch.java
com/neurosky/thinkgear/EkgParameters.class
com/neurosky/thinkgear/EkgParameters.java
com/neurosky/thinkgear/EkgTemplate.class
com/neurosky/thinkgear/EkgTemplate.java
com/neurosky/thinkgear/Matlab.class
com/neurosky/thinkgear/Matlab.java
com/neurosky/thinkgear/EkgSense.class
com/neurosky/thinkgear/EkgSense.java
com/neurosky/thinkgear/DistanceArray.class
com/neurosky/thinkgear/DistanceArray.java

и ниже javap --classpath

osx:/Users/me/Documents/workspace> javap -classpath /Users/me/Documents/workspace/EKGTest.jar    com.neurosky.thinkgear.EkgEpoch
Compiled from "EkgEpoch.java"
public class com.neurosky.thinkgear.EkgEpoch extends java.lang.Object implements java.lang.Cloneable{
    public int numberOfSamples;
    public float[] data;
    public com.neurosky.thinkgear.EkgEpoch(int);
    public com.neurosky.thinkgear.EkgEpoch(int, float[]);
    public com.neurosky.thinkgear.EkgEpoch(float[]);
    public com.neurosky.thinkgear.EkgEpoch(com.neurosky.thinkgear.EkgEpoch);
    public com.neurosky.thinkgear.EkgEpoch(org.json.JSONArray);
    public org.json.JSONArray toJSONArray();
    public static float[] convolve(float[], float[]);
    public float getLineNoiseAmplitude();
    public com.neurosky.thinkgear.EkgEpoch subtract(com.neurosky.thinkgear.EkgEpoch);
    public com.neurosky.thinkgear.EkgEpoch subEpoch(int, int);
    public com.neurosky.thinkgear.EkgEpoch square();
    public com.neurosky.thinkgear.EkgEpoch subtract(float);
    public com.neurosky.thinkgear.EkgEpoch diff();
    public boolean exceedValue(float, int, int);
    public com.neurosky.thinkgear.EkgEpoch smooth(int);
    public float mean();
    public float sum();
    public float max();
    public float median();
    public com.neurosky.thinkgear.EkgEpoch clone();
    public com.neurosky.thinkgear.EkgEpoch sort();
    public int[] sortIndices(com.neurosky.thinkgear.EkgEpoch);
    public float std();
    public int find_heart_beats(int[], float);
    public com.neurosky.thinkgear.EkgEpoch detrend();
    public java.lang.Object clone()       throws java.lang.CloneNotSupportedException;
}

osx:/Users/me/Documents/workspace> javap -classpath /Users/me/Documents/workspace/EKGTest.jar  com.neurosky.thinkgear.EkgSense
Compiled from "EkgSense.java"
public class com.neurosky.thinkgear.EkgSense extends java.lang.Object{
    public com.neurosky.thinkgear.EkgParameters params;
    public com.neurosky.thinkgear.EkgTemplate[] templates;
    public com.neurosky.thinkgear.EkgTemplate currentData;
    public int lastTemplateInd;
    public float lastEpochValue;
    public com.neurosky.thinkgear.EkgSense(com.neurosky.thinkgear.EkgParameters);
    public void reset();
    public void addTemplate(java.lang.String, float[][]);
    public void addTemplate(com.neurosky.thinkgear.EkgTemplate);
    public java.lang.String getClassificationResults();
    public boolean processData(float[]);
}

Я использую Matlab на OSX.Я пытался с Matlab 7.7.0.471 (R2008b) и 7.11.0.584 (R2010b) и получил ту же проблему.Оба Matlab используют собственную OSX Java (Java 1.6.0_26-b03-384-10M3425 с Apple Inc. Java HotSpot (TM) 64-битный сервер, смешанный режим виртуальной машины), который должен быть таким же, как в Eclipse (я проверили Eclipse компилируется с 1.6).

Помните, что без проблем вижу пропущенный класс, когда удаляю инструкцию package и некоторые операции импорта в верхней части java-файлов (во всех классах, конечно) и когда япросто добавьте путь к файлам .class (не обращайтесь к ним в файле JAR).

Любая помощь будет принята с благодарностью.Спасибо,

Джейсон

Ответы [ 6 ]

16 голосов
/ 14 декабря 2011

В конце концов я обнаружил проблему, которую нельзя увидеть выше.Проблема (нигде не документированная) заключалась в том, что некоторые из моих классов используют внешние пакеты, которые я не импортировал в Matlab.Я не планировал использовать какие-либо функции, связанные с этими пакетами.

Тем не менее, сообщение об ошибке Matlab, что он не может найти класс, озадачивает.Сообщение об ошибке, указывающее, что класс не может использоваться, потому что на некоторые пакеты не ссылаются, было бы наиболее полезным.

Если ваш пакет использует внешние пакеты, убедитесь, что включили все соответствующие файлы jar в javaclasspath или Matlab не увидят ваши зависимые классы.

Еще один полезный совет, который я нашел, заключается в том, что функция импорта "Matlab" не вернет ошибку, если вы введете несуществующий пакет, например:import java.doesnotexist.* отлично работает.Однако import java.doesnotexist.aclass не будет работать.

Джейсон

1 голос
/ 29 января 2014

Другая причина, по которой MATLAB не увидит класс, - это когда вы компилируете для JRE7 и используете MATLAB 2012b (вероятно, применимо к другим версиям MATLAB).

Симтом является крайне хромой ошибкой

The class "JavaNuServer" is undefined.
Perhaps Java is not running.

Решение:

Компилировать с флагами javac

-source 1.6 -target 1.6 
0 голосов
/ 04 апреля 2019

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

В этом случае один из моих java-классов прекрасно работал в Matlab2017b после добавления дополнительных jar-файлов вдинамический classpath через javaaddpath как предложено выше.Это предотвратило возникновение исключения java.lang.ClassNotFoundException.

Такой же подход не удался в Matlab2019a.

Теперь я решил, что моя проблема решается простым добавлением моей 'uber' банки, содержащей все банки.моему приложению нужен файл classpath.txt, например:

   # DO NOT MODIFY THIS FILE.  IT IS AN AUTOGENERATED FILE.

/Users/andyhueni/Desktop/SPECCHIO_new_build2/SPECCHIO.app/Contents/Java/specchio-client.jar

$matlabroot/java/patch
$matlabroot/java/jar/jmi.jar
...

Расположение в classpath.txt (верх или конец файла) не имеет значения.

Изменение classpath.txt может быть недоступно для всех пользователей, но в этом превосходном источнике информации перечислены обходные пути: https://undocumentedmatlab.com/blog/static-java-classpath-hacks

0 голосов
/ 30 марта 2017

Я столкнулся с той же проблемой только сейчас. Решение состоит в том, чтобы обновить версию Java Matlab, установив новый параметр envir, упомянутый здесь

https://cn.mathworks.com/matlabcentral/answers/130359-how-do-i-change-the-java-virtual-machine-jvm-that-matlab-is-using-on-windows

Matlab сосет в сообщении об ошибке

0 голосов
/ 26 июля 2016

Эта же проблема может быть вызвана несколькими типами сбоев.(Все они разочаровывают, так как вы не получаете никакой информации о том, что не удалось!) Принятый ответ описывает одну причину и решение.В ответе Вольфганга Куена возникла еще одна возможная проблема, хотя у меня возникли проблемы с пониманием этого вопроса, поэтому я решил написать свой собственный ответ, расширив его чуть более широко:

Каждая версия Matlab поставляется с определенным JRE, который работаети поддерживается.Другая версия корабля Matlab с другой версией JRE.Независимо от того, какая версия Matlab и связанной с ней JRE у вас есть, если вы выполнили свои внешние классы Java, содержащиеся в файле jar, с более высокой (и несовместимой) версией компилятора Java, Matlab откажется подтверждать классы, даже если они находятся вбанкаЕсли вам повезет, вы можете исправить это, перекомпилировав Java с флагом, указывающим совместимость с версией Java в вашем экземпляре Matlab.

Чтобы узнать, какая версия Java работает на вашем Matlab, используйте этукоманда в командной строке Matlab:

version -java

0 голосов
/ 18 апреля 2016

В дополнение к принятому ответу - гораздо лучший способ проверить, правильно ли загружен класс Java, чем с помощью команды import. Используйте функцию whereisjavaclassloadingfrom, предоставленную Эндрю Янке в этом ответе .

Мало того, что он скажет вам, загружен ли класс, он также перечислит все банок, в которых этот класс доступен. Очень часто ваш класс маскируется / затеняется другим классом с таким же пакет / название, расположенное в другой банке. Это может случиться, например, если вы попытаетесь использовать более новую библиотеку, чем та, которая поставляется с Matlab, и не размещаете ее над исходной библиотекой в ​​статическом пути к классам Java.

...