无法为包含 Spring 持久性单元的类调用“hadoop jar”命令

Posted

技术标签:

【中文标题】无法为包含 Spring 持久性单元的类调用“hadoop jar”命令【英文标题】:Unable to invoke 'hadoop jar' command for class, which contains Spring persistance unit 【发布时间】:2013-06-03 06:51:36 【问题描述】:

问题在于,jar 文件使用 Spring ORM 来加载持久性配置,并根据这些配置将文件移动到 HDFS 中的合适文件夹中。现在如果我使用“java -cp”而不是“hadoop jar”,它无法复制到 HDFS,并出现 FileSystem 错误。

使用 hadoop jar 命令调用 jar 时(注入 spring orm)异常如下:

线程“主”org.springframework.beans.factory.BeanCreationException 中的异常:创建名称为 bean 时出错

'org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0' 在类路径资源 [applicationContext.xml

中定义

在类中定义名称为“entityManagerFactory”的 bean 创建错误 路径资源 [applicationContext.xml]:init 方法的调用 失败的;嵌套异常是 java.lang.IllegalStateException: 名称“持久性”的持久性单元定义冲突: 文件:/home/user/Desktop/ABC/apnJar.jar, 文件:/tmp/hadoop-ABC/hadoop-unjar2841422106164401019/

原因:java.lang.IllegalStateException:冲突持久性 名称“持久性”的单位定义

似乎 Hadoop 正在将 jar 文件解压缩到某个 tmp 文件夹,这真的需要吗? 我们可以通过任何配置更改跳过这一步吗?

欢迎对此提出任何想法。

【问题讨论】:

您能否发布您的 shell 调用行,以及您在作业中的哪个位置收到此错误消息(在作业提交期间,在 map/reduce 任务时间?) 【参考方案1】:

如果您使用“hadoop jar”,hadoop 将运行 org.apache.hadoop.util.RunJarRunJar 会将您的 jar 解包到一个临时文件夹中(在您的情况下是 /tmp/hadoop-ABC/hadoop-unjar2841422106164401019/)并将其加载到当前的类加载器中。最后,它将调用您的主类来运行您的 MapReduce 应用程序。

您是否将 jar 添加到 CLASSPATH 中?如果是这样,您将在类加载器中拥有您的 jar 和未打包的文件夹。我想这就是 spring 抱怨它的原因。

【讨论】:

感谢您的回复。该 jar 在我执行命令的位置可用。在命令行中是否有任何选项不解包它? 我找不到任何选项。你可以在这里查看 RunJar 的代码:grepcode.com/file/repository.cloudera.com/content/repositories/… 你可以尽量不要在CLASSPATH中添加你的jar。 是的..得到了问题...配置文件(持久性)也可以在 jar 文件中使用,因此在 unjar 时,它也会在 tmp 位置创建这些文件的副本,结果,有两个同名的持久化单元,因此会产生冲突【参考方案2】:

作为一种解决方法,我从 jar 中提取了配置 xml,并将它们放在工作目录中。

这可行,但正在寻找合适的解决方案。

因此,如果您遇到类似的问题,请删除所有配置 xml,并将仅包含已编译类文件的 jar 放入。

【讨论】:

以上是关于无法为包含 Spring 持久性单元的类调用“hadoop jar”命令的主要内容,如果未能解决你的问题,请参考以下文章

“找不到名为'product'的持久性单元”

Flowable入门系列文章71 - JPA用法

Spring - 没有可用于当前线程的实际事务的 EntityManager - 无法可靠地处理“持久”调用

Spring事务

“找不到名称为 'product' 的持久性单元”

如何在 Spring Boot 应用程序中为带有 @Configuration 注释的类编写单元测试用例