我想在 Jboss 上部署多个 grails 应用程序。因为它们都使用相同的 grails 版本(2.1.1),所以我想从 war 文件中排除常见的 jar 并通过 Jboss 模块提供它们。对于初学者来说,我正在尝试使用一个应用程序,但无法让它工作。
我尝试过的
- Set BuildConfig.groovy 中的
defaultDependencyProvided true
(在inherits("global")
之前) - 创建了模块文件夹:modules/commons/grails/main 并将所有公共(public) jar 放入
- 已创建 module.xml
- 在 war 内的 MANIFEST.MF 文件中添加了
依赖项:commons.grails
- 尝试部署应用
发生了什么
10:16:12,800 INFO [org.jboss.as.server.deployment] (MSC service thread 1-3) JBAS015876: Starting deployment of "sofmk13-web-0.1.war"
10:16:23,095 WARN [org.jboss.modules] (MSC service thread 1-4) Failed to define class org.codehaus.groovy.grails.web.taglib.jsp.JspInvokeGrailsTagLibTag in Module "commons.grails:main" from local module loader @4ec57293 (roots: C:\development\tools\jboss-as-7.1.2.Final\modules,C:\development\repository\jboss): java.lang.LinkageError: Failed to link org/codehaus/groovy/grails/web/taglib/jsp/JspInvokeGrailsTagLibTag (Module "commons.grails:main" from local module loader @4ec57293 (roots: C:\development\tools\jboss-as-7.1.2.Final\modules,C:\development\repository\jboss))
at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:396)
at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:243)
at org.jboss.modules.ModuleClassLoader$1.loadClassLocal(ModuleClassLoader.java:73)
at org.jboss.modules.Module.loadModuleClass(Module.java:527)
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:182)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120)
at java.lang.ClassLoader.defineClass1(Native Method) [rt.jar:1.7.0_17]
at java.lang.ClassLoader.defineClass(ClassLoader.java:791) [rt.jar:1.7.0_17]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) [rt.jar:1.7.0_17]
at org.jboss.modules.ModuleClassLoader.doDefineOrLoadClass(ModuleClassLoader.java:327)
at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:391)
at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:243)
at org.jboss.modules.ModuleClassLoader$1.loadClassLocal(ModuleClassLoader.java:73)
at org.jboss.modules.Module.loadModuleClass(Module.java:527)
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:182)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120)
at java.lang.Class.forName0(Native Method) [rt.jar:1.7.0_17]
at java.lang.Class.forName(Class.java:266) [rt.jar:1.7.0_17]
at org.jboss.as.server.deployment.reflect.DeploymentClassIndex.classIndex(DeploymentClassIndex.java:54)
at org.jboss.as.ee.component.deployers.EEModuleConfigurationProcessor.deploy(EEModuleConfigurationProcessor.java:81) [jboss-as-ee-7.1.2.Final.jar:7.1.2.Final]
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:116)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_17]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_17]
at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_17]
Caused by: java.lang.NoClassDefFoundError: javax/servlet/jsp/tagext/DynamicAttributes
at java.lang.ClassLoader.defineClass1(Native Method) [rt.jar:1.7.0_17]
at java.lang.ClassLoader.defineClass(ClassLoader.java:791) [rt.jar:1.7.0_17]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) [rt.jar:1.7.0_17]
at org.jboss.modules.ModuleClassLoader.doDefineOrLoadClass(ModuleClassLoader.java:327)
at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:391)
... 31 more
Caused by: java.lang.ClassNotFoundException: javax.servlet.jsp.tagext.DynamicAttributes from [Module "commons.grails:main" from local module loader @4ec57293 (roots: C:\development\tools\jboss-as-7.1.2.Final\modules,C:\development\repository\jboss)]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120)
... 36 more
不同类别有很多类似的警告。
有人可以指出我下一步要尝试什么吗?我无法从错误消息中解读到底出了什么问题。
谢谢!
最佳答案
经过一番尝试和错误,我终于成功排除了一些 jar 并将它们作为模块提供。最困难的部分是正确获取所有 jar 依赖项。以下是简要概述。我们首先描述如何准备 war 文件以使用这些模块。然后我们描述如何向jboss添加模块。
准备 WAR 存档(假设已提供模块)
在/web-app/WEB-INF 文件夹中创建 jboss-deployment-struct.xml 文件。在这里,我们指定应用程序使用哪些模块并设置适当的版本(使用插槽参数)。请注意,这些模块提供了我们将在下一步中从 war 中排除的所有 jar。
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0"> <deployment> <dependencies> <module name="commons.restGrailsJars" slot="2.1.1"/> <module name="org.springframework" slot="3.1.2.RELEASE"/> </dependencies> </deployment> </jboss-deployment-structure>
添加代码以从 war 文件中排除共享 jar。我们在 BuildConfig.groovy 中使用 grails.war.resources 配置选项。它允许我们在创建 war 之前进行一些额外的处理,因此我们可以从存档中删除共享 jar(它们列在列表中)。将以下行附加到文件中:
grails.war.resources = { resourceDir -> File libDir = new File(resourceDir, 'WEB-INF/lib') ['aopalliance', 'asm', 'aspectjrt', 'aspectjweaver', 'cglib', 'commons-beanutils', 'commons-codec', 'commons-collections', 'commons-dbcp', 'commons-el', 'commons-fileupload', 'commons-io', 'oro', 'sitemesh', 'slf4j', 'spring-aop', 'spring-asm', 'spring-beans', 'spring-core', 'spring-expression', 'xpp3_min', 'h2', 'servlet-api'] .each { jarNameStart -> libDir.eachFile { file -> if (file.name.startsWith(jarNameStart)) { file.delete() println "deleted jar $file" } } } }
添加 Jboss 模块
如果我们知道每个 jar 库需要哪些依赖项,添加模块就非常容易。下面是为 Spring 版本 3.2.3.RELEASE 添加模块的示例。
- Spring 框架 jar 位于 module/org/springframework 文件夹中。
- 创建名为 3.2.3.RELEASE 的新文件夹,并复制可以共享*的所有 jar。
将module.xml放在 jar 旁边。它看起来像这样:(注意更改了对应于发布版本和文件夹名称的插槽值)
<module xmlns="urn:jboss:module:1.1" name="org.springframework" slot="3.2.3.RELEASE"> <resources> <resource-root path="spring-asm-3.2.3.RELEASE.jar"/> <resource-root path="spring-core-3.2.3.RELEASE.jar"/> <resource-root path="spring-aop-3.2.3.RELEASE.jar"/> <resource-root path="spring-beans-3.2.3.RELEASE.jar"/> <resource-root path="spring-expression-3.2.3.RELEASE.jar"/> </resources> <dependencies> <module name="aopalliance.aopalliance" export="true"/> <module name="cglib.cglib" export="true"/> <module name="org.aspectj.aspectjweaver" export="true"/> <module name="org.apache.commons.logging" export="true"/> <module name="org.apache.commons.pool" export="true"/> <module name="javax.servlet.api"/> <module name="javax.faces.api" slot="1.2" /> <module name="com.sun.jsf-impl" slot="1.2" /> <module name="org.jboss.vfs"/> <module name="javax.persistence.api"/> <module name="javax.xml.bind.api"/> <module name="javax.api"/> <module name="javax.jms.api"/> <module name="javax.annotation.api"/> </dependencies> </module>
如果缺少某些模块,应用程序将无法部署(或者会部署,但会发生奇怪的事情,例如电子邮件验证失败)。
您必须对要从 war 存档中排除的所有库执行类似的操作。我设法排除了“准备 WAR 存档”部分 (2.) 中列出的所有 jar。
关于grails - 使用提供的依赖项在 Jboss 7.1.2 上部署 grails 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16354473/