Matlab在jar包中看不到我的一些java类(不是全部)

时间:2011-12-14 05:32:55

标签: java matlab import jar package

我有一个让我疯狂的问题。 Matlab只看到我的一些类嵌入在JAR文件中

如果我在包外编译类并使用javaaddpath在Matlab中添加类的路径,我不会遇到任何问题

当我在一个包中编译该类然后尝试在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[]);
}

我在OSX上运行Matlab。我尝试过使用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位服务器VM混合模式),它应该与Eclipse中的相​​同(我已经检查过)和Eclipse编译1.6)。

请记住,当我删除包语句时,我可以看到缺少的类没有问题,当然在java文件的顶部(当然在所有类中)都有一些导入,当我只是添加.class文件的路径时不能在JAR文件中访问它们。)

非常感谢任何帮助。 谢谢,

杰森

6 个答案:

答案 0 :(得分:16)

我最终发现了上面无法看到的问题。问题(没有在任何地方记录)是我的一些类使用我没有导入到Matlab的外部包。我没有计划使用与这些软件包相关的任何功能。

尽管如此,它找不到类的Matlab错误信息令人费解。

是一个错误消息,指示由于某些包未被引用而无法使用该类。

如果您的软件包使用外部软件包,请确保在java类路径中包含所有相关的jar文件,否则Matlab将看不到您的依赖类。

我发现另一个有用的提示是,如果你输入一个不存在的包,Matlab函数“import”将不会返回错误,例如,import java.doesnotexist.*工作正常。但是,import java.doesnotexist.aclass将不起作用。

杰森

答案 1 :(得分:1)

MATLAB不会看到类的另一个原因是编译JRE7并使用MATLAB 2012b时(可能适用于其他MATLAB版本)。

symtom是极端蹩脚的错误

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

解决方案:

使用javac标志编译

-source 1.6 -target 1.6 

答案 2 :(得分:0)

为了补充已接受的答案 - 有一种更好的方法来检查java类是否被加载,而不是通过import命令。使用Andrew Janke在this answer中提供的whereisjavaclassloadingfrom函数。

它不仅会告诉你是否加载了这个类,它还会列出这个类可用的所有 jar。很多时候,你的类被另一个类掩盖/遮盖了相同的包装/名称,位于不同的罐子里。这可能发生在例如如果你尝试使用比Matlab附带的库更新的库,并且不要将它放在静态java类路径上的原始库之上。

答案 3 :(得分:0)

同样的问题可能是由多种类型的故障引起的。 (所有这些令人沮丧,因为你没有得到关于失败的信息!)接受的答案描述了一个原因和解决方案。沃尔夫冈·库恩的答案得到了另一个可能的问题,虽然我很难理解这一点,所以我决定写一些自己的答案,稍微扩大一点:

每个版本的Matlab都附带了一些运行和支持的特定JRE。不同版本的Matlab附带不同版本的JRE。无论您使用哪个版本的Matlab和相关的JRE,如果您使用更高(且不兼容)的Java编译器版本来编写jar文件中的外部Java类,Matlab将拒绝承认类,即使它们在罐子。如果幸运的话,可以通过重新编译Java来解决这个问题,该标志指定了与Matlab实例中Java版本的兼容性。

要了解Matlab运行的Java版本,请在Matlab命令提示符下使用此命令:

version -java

答案 4 :(得分:0)

我刚才遇到了同样的问题。 解决方案是通过设置此处提到的新envir参数来更新matlab java版本

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

Matlab糟透了错误消息

答案 5 :(得分:0)

发生这种情况的另一个原因是需要某些类位于Matlab的静态类路径中。

在这种情况下,在如上所述通过javaaddpath将更多jar添加到动态类路径中之后,我的一个Java类在Matlab2017b中完美地工作了。这阻止了java.lang.ClassNotFoundException的发生。

同样的方法在Matlab2019a中失败了。

现在,我发现只需将包含应用程序所需的所有jar的“超级” jar添加到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