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

cod*_*het 5 java websphere java-ee gradle

我有一个简单的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
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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

[*] 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
Run Code Online (Sandbox Code Playgroud)

我正在使用Websphere Test Environment v8.5.5.0

更新:我怀疑也许压缩算法用于压缩耳朵文件可能是责备,似乎我是对的; 使用7zip解压缩和重新传输ear文件导致部署无错误地工作.

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

这引出了一个新问题:

  1. 如何控制ear文件的汇编/压缩以符合Websphere的预期?

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

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

更新3:好像我一直在追逐红鲱鱼.我已经检查了应该正确部署的文件并且看到耳朵在耳根上方有一个额外的文件夹级别(即app.ear!app/<root>).

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

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

  • 而不是application.xml中的java模块我有ejb模块
  • 我在core.jar中包含了一个基本的META-INF/ejb-jar.xml文件(尽管规范说你不需要它们),因为当它丢失时,websphere显然不喜欢它
  • 我从application.xml中删除了core-api.jar模块

所以我现在有以下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>
Run Code Online (Sandbox Code Playgroud)

最后一个问题:如何将一个工件"部署"到一个耳朵项目而不将其添加到应用程序xml中?或者,如何在部署解决后自定义application.xml?

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

虽然应用程序已成功部署,但它没有启动,给我一个错误,说我的ejb jar没有ejbs.我已经决定,根据我收到的建议以及下面的答案,我的春季罐子被归类为"实用"罐子,应该存在于lib文件夹中.

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

这是我最后的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>
Run Code Online (Sandbox Code Playgroud)

感谢您的时间和耐心.

gro*_*roo 3

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

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

app.ear
|-- lib/$UTILITY_JARS_HERE
|-- EJB.jars
|-- web.war
Run Code Online (Sandbox Code Playgroud)

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

现在,如果您将 EJB 2.x 与打包一起使用,那么您需要 application.xml 并声明您的 ejb 和 war,您应该保留将实用程序 jar 保留在 lib 文件夹中的推荐方法以及那些仅由 war 包的 lib 文件夹内的 Web 层需要。

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

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