草庐IT

java - 从 Matlab 创建的 jar 文件返回值

coder 2024-03-10 原文

我有一个 Matlab 代码,它最终计算出一个索引 vector 。我使用库编译器将 matlab 代码编译为 java 包 .jar 文件。我导出了 jar 文件以便为我的主要 Java 项目运行它。包类的名称是 Epidemic。我导入了 jar 文件(将其添加为外部 jar)。在主代码中,我试图创建我的类的一个对象(在 jar 文件中)。我已经将类的名称定义为 Epidemic。因此,我的代码:

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

我使用 project->Libraries 右键单击​​添加外部 jar 将 .jar 文件添加到 java 项目。 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

这里有什么问题?我是否应该添加其他东西以使 jar 正常工作?

编辑:我将位于 MATLABROOT/toolbox/javabuild/jar/javabuild.jar 中的 .jar 文件添加到我的类路径和它似乎可以工作的类中。现在我面临另一个问题。当我打印基于 html 文档的 list1 获取 matlab .m 文件的输出时,我得到了一个空的 arrayList。 Matlab 函数返回一个 double 组 Nx1。我怎样才能将它正确解析为 java arrayList。

我的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 cannot be cast to java.lang.Double。当我只打印结果时

最佳答案

有两件事需要添加到 Java 项目类路径中:

  • 您部署的 JAR 文件 created来自 MATLAB 代码。
  • Java Builder自己的 JAR 文件。如果目标计算机上安装了 MATLAB,则可以在 $MATLABROOT\toolbox\javabuilder\jar\javabuilder.jar 中找到它们,否则安装相应的 MCR运行时(免费提供),并在类似的路径中找到 JAR 文件。

参见 here获取完整说明。


编辑:

为了完整起见,下面是一个工作示例。

  1. 假设我们有以下返回数字数组的 MATLAB 函数。

    流行病.m

    function list = epidemic()
        list = randi(100, [1, 10]);
    end
    
  2. 使用 applicationCompiler MATLAB 应用程序,创建一个新项目以构建“Java 包”。将上述函数添加到项目中,设置类名和方法名,然后构建包。我们应该得到一个 JAR 文件,比如:Epidemic.jar

  3. 接下来我们创建一个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();
            }
        }
    }
    
  4. 最后编译运行测试程序:

    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 个 double 字的数组。

关于java - 从 Matlab 创建的 jar 文件返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27374534/

有关java - 从 Matlab 创建的 jar 文件返回值的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  4. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  5. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  6. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  7. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  8. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  9. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  10. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

随机推荐