java Hello World Ear:NoModuleFileException:不存在具有 uri 的模块元素的文件:core-api.jar

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25006537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 07:08:38  来源:igfitidea点击:

Hello World Ear: NoModuleFileException: A file does not exist for module element having uri: core-api.jar

javajakarta-eegradlewebsphere

提问by coderatchet

I have what is a simple EAR file configured like so:

我有一个简单的 EAR 文件,配置如下:

app.ear
|-- lib/...
|-- META-INF/application.xml
|-- core.jar
|   |-- test/MyServiceImpl.class
|   `-- META-INF/MANIFEST.MF // Class-Path: core-api.jar 
|-- core-api.jar
|   `-- test/MyService.class
`-- web.war
    `-- META-INF/MANIFEST.MF // Class-Path: core.jar core-api.jar

The application.xml is as follows:

application.xml 如下:

<?xml version="1.0"?>
<application xmlns="http://java.sun.com/xml/ns/javaee" id="app 1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" version="6">
  <application-name>MyApp</application-name>
  <display-name>My App</display-name>
  <module id="mod 1">
    <java>core-api.jar</java>
  </module>
  <module id="mod 2">
    <java>core.jar</java>
  </module>
  <module id="mod 3">
    <web>
      <web-uri>web.war</web-uri>
      <context-root>/</context-root>
    </web>
  </module>
  <library-directory>lib</library-directory>
</application>

When i attempt to deploy the application to the server, I get the following exception:

当我尝试将应用程序部署到服务器时,出现以下异常:

[*] 00000088 SystemErr     R Caused by: org.eclipse.jst.j2ee.commonarchivecore.internal.exception.NoModuleFileException: A file does not exist for module element having uri: core-api.jar
[*] 00000088 SystemErr     R    at org.eclipse.jst.j2ee.commonarchivecore.internal.impl.ModuleRefImpl.checkType(ModuleRefImpl.java:591)
[*] 00000088 SystemErr     R    at org.eclipse.jst.j2ee.commonarchivecore.internal.impl.ModuleRefImpl.initModuleFileFromEAR(ModuleRefImpl.java:167)
[*] 00000088 SystemErr     R    at org.eclipse.jst.j2ee.commonarchivecore.internal.impl.ModuleRefImpl.getModuleFile(ModuleRefImpl.java:120)
[*] 00000088 SystemErr     R    at org.eclipse.jst.j2ee.commonarchivecore.internal.impl.EARFileImpl.getModuleFile(EARFileImpl.java:165)
[*] 00000088 SystemErr     R    at org.eclipse.jst.j2ee.commonarchivecore.internal.impl.EARFileImpl.getDeploymentDescriptor(EARFileImpl.java:817)
[*] 00000088 SystemErr     R    at org.eclipse.jst.j2ee.commonarchivecore.internal.impl.ModuleRefImpl.getDeploymentDescriptor(ModuleRefImpl.java:230)
[*] 00000088 SystemErr     R    ... 49 more

I am using Websphere Test Environment v8.5.5.0

我正在使用 Websphere 测试环境 v8.5.5.0

UPDATE:I suspected maybe the compression algorithm used to zip the ear file may be to blame and it seems as though I was right; unzipping and rezipping the ear file using 7zip caused the deployment to work without errors.

更新:我怀疑用于压缩耳朵文件的压缩算法可能是罪魁祸首,似乎我是对的;使用 7zip 解压缩和重新压缩 ear 文件导致部署工作没有错误。

I am using gradle as a build tool which provides it's own mechanism for zipping archives. I have tried setting the entryCompressionmode to ZipEntryCompression.STOREDwithout success.

This leads me to a new question:

  1. How can i control the assembly/compression of the ear file to conform with what Websphere expects?

    and

  2. What method does gradle use to compress the ear?

我使用 gradle 作为构建工具,它提供了自己的压缩档案机制。我尝试将entryCompression模式设置为ZipEntryCompression.STORED没有成功。

这让我想到了一个新问题:

  1. 我如何控制 Ear 文件的组装/压缩以符合 Websphere 的预期?

  2. gradle用什么方法压缩耳朵?

UPDATE 2:Looking at the gradle source code, I can see the Zip implementation uses ant's org.apache.tools.zip.ZipOutputStream(1.9.3). has anyone had difficulty with this process before?

更新 2:查看 gradle 源代码,我可以看到 Zip 实现使用了 ant org.apache.tools.zip.ZipOutputStream(1.9.3)。以前有人在这个过程中遇到困难吗?

UPDATE 3:It seems as if I've been chasing a red herring. I have inspected the file that supposedly deployed correctly and saw that the ear contained an extra folder level above the root of the ear (that is app.ear!app/<root>).

更新 3:好像我一直在追逐红鲱鱼。我检查了应该正确部署的文件,发现耳朵在耳朵根部(即app.ear!app/<root>)上方包含一个额外的文件夹级别。

assuming that compression algorithms have nothing to do with it, does anyone have any ideas?

假设压缩算法与它无关,有没有人有任何想法?

UPDATE 4:Ok, I'm really close, I managed to get the deployment working after inspecting some sample ear files and testing various theories. I did these things and it worked(see Update 5).

更新 4:好的,我真的很接近,在检查了一些样本耳朵文件并测试了各种理论后,我设法使部署工作。我做了这些事情并且它奏效了(参见更新 5)。

  • Instead of java modules in the application.xml i have ejb modules
  • I included a basic META-INF/ejb-jar.xml file in the core.jar (even though the spec says you don't need them) as websphere apparently does not like it when it's missing
  • I removed the core-api.jar module from the application.xml
  • 我有 ejb 模块,而不是 application.xml 中的 java 模块
  • 我在 core.jar 中包含了一个基本的 META-INF/ejb-jar.xml 文件(即使规范说你不需要它们),因为 websphere 在它丢失时显然不喜欢它
  • 我从 application.xml 中删除了 core-api.jar 模块

So i now have the following application.xml:

所以我现在有以下 application.xml:

<?xml version="1.0"?>
<application ...>
  <application-name>MyApp</application-name>
  <display-name>My App</display-name>
  <module id="mod 1">
    <ejb>core.jar</ejb>
  </module>
  <module id="mod 2">
    <web>
      <web-uri>web.war</web-uri>
      <context-root>/</context-root>
    </web>
  </module>
  <library-directory>lib</library-directory>
</application>

One last question: how can i 'deploy' an artifact to an ear project without adding it to the application xml? alternatively, how can i customize the application.xml after the deployments have been resolved?

最后一个问题:如何在不将工件添加到应用程序 xml 的情况下将工件“部署”到耳朵项目?或者,如何在部署解决后自定义 application.xml?

UPDATE 5:Apologies for the fluctuating state of my question.

更新 5:为我的问题的波动状态道歉。

Although the application successfully deployed, it did not start up, giving me an error saying that my ejb jars had no ejbs. I have since decided, following the advice I have received and also an answer below, that my spring-based jars are classed as "utility" jars and should live in the lib folder.

虽然应用程序成功部署,但它没有启动,给我一个错误,说我的 ejb jars 没有 ejbs。从那以后,我根据收到的建议和下面的回答决定,我的基于 spring 的 jar 被归类为“实用程序”jar,应该放在 lib 文件夹中。

I am expecting to use these jars in EJBs in the future and so wish to keep them in the lib folder instead of directly in the war.

我希望将来在 EJB 中使用这些 jar,因此希望将它们保存在 lib 文件夹中,而不是直接保存在 war 中。

this is my final application.xml:

这是我的最终 application.xml:

<?xml version="1.0"?>
<application ...>
  <application-name>MyApp</application-name>
  <display-name>My App</display-name>
  <module>
    <web>
      <web-uri>web.war</web-uri>
      <context-root>/</context-root>
    </web>
  </module>
  <library-directory>lib</library-directory>
</application>

Thank you for your time and patience.

感谢您的时间和耐心。

采纳答案by groo

Well I can see by your application.xml header that you're using JavaEE 6 packaging and you also mentioned you're using WebSphere 8.5.5 so follow some ear packaging information.

好吧,我可以通过您的 application.xml 标头看到您使用的是 JavaEE 6 打包,并且您还提到您使用的是 WebSphere 8.5.5,因此请遵循一些耳朵打包信息。

You do not need the application.xml at all if you're using annotated EJB 3.x and then follow the standard packaging convention:

如果您使用带注释的 EJB 3.x,然后遵循标准打包约定,则根本不需要 application.xml:

app.ear
|-- lib/$UTILITY_JARS_HERE
|-- EJB.jars
|-- web.war

Notice that this is the default packaging for Java EE 6 structures and following this all utility jars that you place inside the lib directory will be available to both the EJBs and WARs you have there so you should use this directory only if your utility jars are required by both EJBs and web applications. If your utility jar is used only by your web application than you should package them inside the standard WEB-INF/lib folder in you war package only.

请注意,这是 Java EE 6 结构的默认包装,因此,您放置在 lib 目录中的所有实用程序 jar 将可用于您在那里的 EJB 和 WAR,因此只有在需要实用程序 jar 时才应使用此目录通过 EJB 和 Web 应用程序。如果您的实用程序 jar 仅由您的 Web 应用程序使用,那么您应该仅将它们打包在您的 war 包中的标准 WEB-INF/lib 文件夹中。

Now if you're using EJBs 2.x together with your packaging than you'll need to have the application.xml and declare your ejbs and war, you should keep the recommended approach of leaving the utilities jars inside the lib folder and the ones required only by the web layer inside the lib folder of the war package.

现在,如果您将 EJBs 2.x 与您的包装一起使用,那么您将需要拥有 application.xml 并声明您的 ejbs 和 war,您应该保留将实用程序 jars 留在 lib 文件夹中的推荐方法和那些只有war包的lib文件夹内的web层需要。

If for any reason you want to keep your utilities jars at the root level or the ear you can use the approach of declaring them at the Manifest for the EAR but than you DON'T and can't declare them again in the manifest for the war package. All declared jars on the ear manifest will be automatically visible by the classloader of the war file and EJBs.

如果出于任何原因,您想将实用程序 jar 保留在根级别或耳朵,您可以使用在 EAR 的清单中声明它们的方法,但您不要并且不能在清单中再次声明它们War包。耳朵清单上所有声明的 jar 文件将自动被 war 文件和 EJB 的类加载器可见。

The javaEE 6 specifiction Chapter 8 "Application Assembly and Deployment" has the complete explanation on this subject. You can download the document here.

javaEE 6 规范第 8 章“应用程序组装和部署”对这个主题有完整的解释。您可以在此处下载文档。