简体   繁体   English

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

[英]Matlab cannot see some of my java classes (not all) in jar package

I have a problem that is driving me nuts. 我有一个让我疯狂的问题。 Matlab sees only some of my classes embeded in a JAR file Matlab只看到我的一些类嵌入在JAR文件中

If I compile the classes outside of a package and add the path to the class in Matlab using javaaddpath, I do not encounter any problem 如果我在一个包之外编译类并使用javaaddpath在Matlab中添加该类的路径,我没有遇到任何问题

When I compile the class in a package and then try to access them under Matlab, I have problems. 当我在一个包中编译该类然后尝试在Matlab下访问它时,我遇到了问题。 Below some Matlab code 下面是一些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

Now, I look in the package, all of the classes are public. 现在,我查看包中,所有类都是公开的。 This is a result of jar -tf 这是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

and below of javap --classpath 以及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[]);
}

I am running Matlab on OSX. 我在OSX上运行Matlab。 I have tried with Matlab 7.7.0.471 (R2008b) and 7.11.0.584 (R2010b) and got the same problem. 我尝试过使用Matlab 7.7.0.471(R2008b)和7.11.0.584(R2010b)并遇到同样的问题。 Both Matlab are using the native OSX Java (Java 1.6.0_26-b03-384-10M3425 with Apple Inc. Java HotSpot(TM) 64-Bit Server VM mixed mode) which should be the same as the one in Eclipse (I have checked and Eclipse compiles with 1.6). 两个Matlab都使用本机OSX Java(Java 1.6.0_26-b03-384-10M3425与Apple Inc. Java HotSpot(TM)64位服务器VM混合模式),它应该与Eclipse中的相​​同(我已经检查过)和Eclipse编译1.6)。

Remember that I can see the missing class no problem when I remove the package statement and some imports at the top of the java files (in all the classes of course) and when I simply add the path to the .class files (not access them in a JAR file). 请记住,当我删除package语句并在java文件的顶部(当然在所有类中)导入一些导入时,我可以看到缺少的类没有问题,当我只是添加.class文件的路径时(不能访问它们)在JAR文件中)。

Any help would be greatly appreciated. 任何帮助将不胜感激。 Thanks, 谢谢,

Jason 贾森

I eventually found the problem which cannot be seen above. 我最终发现了上面无法看到的问题。 The problem (not documented anywhere) was that some of my classes use external packages that I had not imported into Matlab. 问题(没有在任何地方记录)是我的一些类使用我没有导入到Matlab的外部包。 I was not planning on using any of the functionalities linked with these packages. 我没有计划使用与这些软件包相关的任何功能。

Nevertheless, the Matlab error message that it cannot find the class is puzzling. 尽管如此,它找不到类的Matlab错误信息令人费解。 An error message indicating that the class cannot be used because some packages are not referenced would be most useful. 指示由于某些包未被引用而无法使用该类的错误消息将是最有用的。

If your package uses external packages, make sure to include all of the relevant jar files in the java classpath or Matlab will not see your dependent classes. 如果您的包使用外部包,请确保在java类路径中包含所有相关的jar文件,否则Matlab将看不到您的依赖类。

Another tip that I found useful is that the Matlab function "import" will not return an error if you enter a package that does not exist, eg, import java.doesnotexist.* works fine. 我发现另一个有用的提示是,如果输入一个不存在的包,Matlab函数“import”将不会返回错误,例如import java.doesnotexist.*工作正常。 However, import java.doesnotexist.aclass will not work. 但是, import java.doesnotexist.aclass将不起作用。

Jason 贾森

Another reason MATLAB will not see a class is when you compile for JRE7 and are using MATLAB 2012b (probably applies to other MATLAB releases). MATLAB不会看到类的另一个原因是编译JRE7并使用MATLAB 2012b时(可能适用于其他MATLAB版本)。

The symtom is the extremly lame error symtom是极端蹩脚的错误

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

Solution: 解:

Compile with the javac flags 使用javac标志进行编译

-source 1.6 -target 1.6 

To complement the accepted answer - there's a far better way to check if java class was loaded propertly, than through import command. 为了补充已接受的答案 - 有一种更好的方法来检查java类是否被加载属性,而不是通过import命令。 Use whereisjavaclassloadingfrom function, provided by Andrew Janke in this answer . 这个答案中使用Andrew Janke提供的whereisjavaclassloadingfrom function。

Not only it will tell you whether the class is loaded, it will list all jars that this class is available in. It happens quite often that your class gets masked / overshadowed by another class with the same package/name, located in a different jar. 它不仅会告诉你是否加载了这个类,它还会列出这个类可用的所有 jar。它经常发生在你的类被另一个具有相同包/名称的类掩盖/遮盖,位于不同的jar中。 That can happen eg if you try to use a newer library than one of those shipped with Matlab, and do not place it above the original one on the static java classpath. 这可能发生,例如,如果您尝试使用比Matlab附带的库更新的库,并且不要将它放在静态java类路径上的原始库之上。

This same problem can be caused by multiple types of failures. 多种类型的故障都可能导致同样的问题。 (All of them frustrating since you get NO information about what failed!) The accepted answer describes one reason and the solution. (所有这些令人沮丧,因为你没有得到关于失败的信息!)接受的答案描述了一个原因和解决方案。 The answer by Wolfgang Kuehn gets at another possible issue, although I had trouble understanding the point so I decided to write my own answer expanding on it slightly more generally: Wolfgang Kuehn的回答得到了另一个可能的问题,虽然我很难理解这一点,所以我决定写一些自己的答案,稍微扩展一下:

Each version of Matlab ships with some specific JRE that's run and supported. 每个版本的Matlab都附带一些运行和支持的特定JRE。 Different version of Matlab ship with different version of the JRE. 不同版本的Matlab附带不同版本的JRE。 Not matter which version of Matlab and associated JRE you have though, if you complied your external Java classes that are in the jar file with a higher (and incompatible) version of the Java compiler, Matlab will refuse to acknowledge classes even though they are in the jar. 无论您使用哪个版本的Matlab和相关的JRE,如果您使用更高(且不兼容)的Java编译器版本来编写jar文件中的外部Java类,Matlab将拒绝承认类,即使它们在罐子。 If you're lucky, you can fix this by recompiling the Java with a flag specifying compatibility with the version of Java in your instance of Matlab. 如果你很幸运,你可以通过重新编译Java来解决这个问题,该标志指定了与你的Matlab实例中Java版本的兼容性。

To find out which version of Java your Matlab is running, use this command at the Matlab command prompt: 要找出Matlab正在运行的Java版本,请在Matlab命令提示符下使用此命令:

version -java

I encountered the same problem just now. 我刚才遇到了同样的问题。 The solution is to update matlab java version by setting a new envir parameter mentioned here 解决方案是通过设置此处提到的新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 https://cn.mathworks.com/matlabcentral/answers/130359-how-do-i-change-the-java-virtual-machine-jvm-that-matlab-is-using-on-windows

Matlab sucks at error message Matlab糟透了消息

One more reason why this is happening is the need of some classes to be in the static classpath of Matlab. 发生这种情况的另一个原因是需要一些类在Matlab的静态类路径中。

In this case, one of my java classes worked perfectly in Matlab2017b after adding more jars to the dynamic classpath via javaaddpath as suggested above. 在这种情况下,如上所述,在通过javaaddpath向动态类路径添加更多jar之后,我的一个java类在Matlab2017b中完美运行。 That prevented the java.lang.ClassNotFoundException from happening. 这阻止了java.lang.ClassNotFoundException的发生。

The same approach failed in Matlab2019a. 相同的方法在Matlab2019a中失败了。

Now I figured that my problem is solved by simply adding my 'uber' jar containing all the jars my application needs to the classpath.txt file, like so: 现在我想通过简单地将包含我的应用程序所需的所有jar的'uber'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
...

The location within the classpath.txt (top or end of the file) appears to be of no importance. classpath.txt(文件的顶部或末尾)内的位置似乎并不重要。

Modifying the classpath.txt may not be possible for all users, but there are work-arounds as listed on this excellent source of information: https://undocumentedmatlab.com/blog/static-java-classpath-hacks 修改classpath.txt可能不适用于所有用户,但是这些优秀的信息源中列出了解决方法: https//undocumentedmatlab.com/blog/static-java-classpath-hacks

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM