【问题标题】:Java JPA Class for MATLAB用于 MATLAB 的 Java JPA 类
【发布时间】:2011-05-21 13:34:49
【问题描述】:

我在 Windows XP Pro SP3 上使用 MATLAB R2007b、Java 1.6 SE、Eclipse Helios 和 MySql 5。

我正在尝试创建一个使用 JPA 注释来访问 MySql 5 数据库的类库。这个想法是 MATLAB 脚本实例化这些 Java 对象,这些对象提供了一个用于访问数据库的 API。

我可以创建在 Eclipse 中工作的带注释的类(即 JUnit 测试)。我可以将代码导出到 jar 中,我可以在命令提示符下运行它。

我使用 javaaddpath() 更新了 MATLAB Java 类路径。我可以在 MATLAB 中实例化我的类。但是当我调用我的 init(),它调用 javax.persistence.Persistence.createEntityManagerFactory(),我感到害怕

“EntityManager 没有持久性提供程序”

这个错误通常意味着persistence.xml 文件不在正确的位置。但这一定是因为我的 jar 从命令行工作。将 META-INF 文件夹添加到 MATLAB java 类路径没有帮助。也不会提取 jar 并将提取的文件夹结构添加到类路径中,无论是否添加了 META-INF。

有没有人有任何想法,疯狂与否?有没有人在任何版本的 MATLAB 中这样做过。

谢谢。

-赖利。

【问题讨论】:

  • 类路径上有持久性提供程序吗?
  • 考虑升级 Matlab。 R2007b 很旧,它的嵌入式 JVM 是 Java 1.5。它可能不会导致此问题,但它可能会使您的其他开发更加顺利。

标签: java matlab jpa classpath


【解决方案1】:

嗯,我找到了“答案”。在我看到一篇关于 MATLAB 的“动态”和“静态”cp 差异的帖子之前的某个地方。 “静态”cp 是在启动时加载的文本文件。 “动态” cp 在运行时加载,您通常使用 m 脚本调用来操作它。这就是我想要做的。

所以我将我的 jars 添加到动态路径中,但它不起作用。

我将它们添加到静态路径的末尾并得到不同的错误,这似乎与 XML 解析有关。进步!

然后我将我的罐子添加到静态路径的开头,它可以工作。

引用 Bart Simpson:Craptackular。

感谢您的所有想法。问我一个 C# 问题,这样我就可以报答...

-赖利。

【讨论】:

  • 有道理——静态类路径对应于系统类加载器;动态类路径是使用自定义 Matlab URLClassLoader 完成的。像 JAX-WS 这样需要激活类的 API 可能会遇到问题,因为静态类路径上的 API 类无法“看到”加载到动态类路径中的类定义; JPA 可能有同样的问题。如果要修改静态类路径,则可以在启动 Matlab 的目录中使用自定义 classpath.txt,而不是在 Matlab 安装本身中编辑 classpath.txt;更容易维护。
  • 谢谢,安德鲁。我不知道我自己的 classpath.txt。这解决了我对这个问题的主要抱怨。
  • 为了记录和交叉参考,这是 Reilly 在 CSSM 上谈论的帖子:mathworks.com/matlabcentral/newsreader/view_thread/…
【解决方案2】:

在 MATLAB 中使用 Java 时,我经常遇到 动态类路径 的问题。作为一种解决方法,到目前为止,使用classpath.txt 已经解决了所有问题。

处理不同的环境,例如测试和生产,会在您的 MATLAB 启动目录中产生多个 classpath.txt 文件。使用不同的 MATLAB 版本会为周围的 classpath.txt 文件数量增加另一个倍数。

ClassPathHacker.java 是一个将动态 类和jar 文件添加到static 类路径的选项。使用这种方法,不再需要触摸classpath.txt。您的 Java 类路径配置可以保留在预期的位置 startup.m

【讨论】:

  • +1 这看起来很有用!我的 Matlab 应用程序实际上确实有那些 nenvironments x nmatlabversions 不同的启动目录和这些自定义文件;这真的可以简化事情。
【解决方案3】:

这只是您对静态与动态类路径的回答的后续。这是一个函数,它可以让您诊断从 Matlab 中加载 Java 类的位置,以及是否有任何对类定义的屏蔽,这可能是它对您的排序敏感的原因。您可能会看到其他碰撞;至少 dom4j.jar 和 commons-collections.jar 是 Matlab 附带的,但我不知道是什么版本。

function whereisjavaclassloadingfrom(ClassName)
%WHEREISJAVACLASSLOADINGFROM  Show where a Java class is loaded from
%
% whereisjavaclassloadingfrom(ClassName)
%
% Shows where a Java class is loaded from in this Matlab session's JVM.
% This is for diagnosing Java class load problems, such as classpath
% ordering issues, seeing if a class of a given name is included in an
% unexpected JAR file, etc.
%
% Displays output to console.
%
% Examples:
%
% whereisjavaclassloadingfrom('java.util.HashMap')
% whereisjavaclassloadingfrom('com.ldhenergy.etools.MxUtil')
% whereisjavaclassloadingfrom('com.google.common.collect.Maps')
% whereisjavaclassloadingfrom('org.apache.commons.math.complex.Complex')

% Use javaArray to get Class object without having to instantiate. This
% lets it work with objects that have private or non-zero-arg constructors,
% and avoids side effects of object construction.
% (Would use java.lang.Class.forName(), because that's a more direct way of
% doing this, but it doesn't work for stuff on the dynamic classpath.)
ja = javaArray(ClassName,1);
klass = ja.getClass().getComponentType();

klassLoader = klass.getClassLoader();
if isempty(klassLoader)
    % JVM used null to represent the "bootstrap" class loader
    % I think that's the same as the "system" class loader
    klassLoader = java.lang.ClassLoader.getSystemClassLoader();
end
klassLoaderStr = char(klassLoader.toString());

klassFilePath = [strrep(ClassName, '.', '/') '.class'];
try
    % This logic assumes that the classes exist as files in the class
    % loader. It's a valid assumption for mainstream class loaders,
    % including the one's I've seen with Matlab.
    klassUrl = klassLoader.getResource(klassFilePath);
    if isempty(klassUrl)
        klassUrlStr = '';
    else
        klassUrlStr = char(klassUrl.toString());
    end
catch err
    klassUrlStr = sprintf('ERROR: %s', err.message);
end

% Get all locations, to reveal masked definitions
urls = enumeration2array(klassLoader.getResources(klassFilePath));

disp(sprintf('Version: %s\nClass:       %s\nClassLoader: %s\nURL:         %s', version,...
    char(klass.getName()), klassLoaderStr, klassUrlStr));
if numel(urls) > 1
    disp('Class is masked:');
    for i = 1:numel(urls)
        disp(sprintf('URL %d:       %s', i, char(urls(i))));
    end
end

%%
function out = enumeration2array(jenum)
tmp = {};
while jenum.hasMoreElements()
    tmp{end+1} = jenum.nextElement();
end
out = [tmp{:}];

【讨论】:

    【解决方案4】:

    确保您的类路径中有 JPA 提供程序 jar(例如 eclipselink.jar)。

    【讨论】:

    • +1 这是一个很好的候选人。 Matlab 管理自己的 Java 类路径,因此它不一定与命令行“java”命令看到的相同。从 R2010b 开始,Matlab 不附带 javax.persistence,因此您需要为其提供 JAR 以及带有您自己的类的 JAR。
    • 是的。这是我的 MATLAB 类路径中的内容:
    • antlr-2.7.6.jar com.barronassociates.auspex.rotorcraft.jar commons-collections-3.1.jar dom4j.jar ejb3-persistence.jar hibernate3.jar hibernate-annotations.jar hibernate-commons -annotations.jar hibernate-core.jar hibernate-entitymanager.jar javassist.jar jta.jar mysql-connector-java-5.1.7-bin.jar slf4j-api-1.5.6.jar slf4j-simple-1.5.6。罐子
    【解决方案5】:

    您是否绝对确定在调用中正确拼写了持久性单元的名称:

    javax.persistence.Persistence.createEntityManagerFactory(String puName)
    

    这也会给你同样的错误。名称区分大小写。

    【讨论】:

    • 是的。持久性单元名称在我的 Java 类中是硬编码的,因此无论我是从 MATLAB 还是从命令行中的 java 运行,都会传递相同的值。
    猜你喜欢
    • 1970-01-01
    • 2015-06-29
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    • 2010-10-24
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    相关资源
    最近更新 更多