且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

WAR部署中的Groovy Grails工具套件NoClassDefFoundError

更新时间:2023-09-21 11:45:46

好的 - 想出来 - 足以让它工作....



[仍然诅咒为什么GG没有选择为了找出哪些JAR文件包含在WAR部署过程中报告丢失的类,我只是做了一个狩猎并啄食了这些JAR文件。 dist文件夹包含安装了Groovy / Grails v2.2.4的Grails JAR(C:\grails-2.2.4\dist)。我用7zip来浏览JAR。由于两个班都在其中有测试一词,因此我首先在名称中使用测试的JARS中查找并轻松找到它们。这就是我弄清楚上面列出的包含这些类的问题的两个JAR文件。



将它们放在服务器上的WEB-INF / lib文件夹中,那么成功启动/部署项目证实,让他们在WAR中可以解决问题。



为了让他们进入项目并在WAR创建时进入WAR ,我做到了这一点......

  1)对所涉及的项目运行grails clean
2)close项目(和所有其他项目)
3)退出g& g工具套件
4)使用Windows资源管理器将jar文件拖到项目的PROJECTNAME / lib目录中。
5)启动g& g工具套件
6)打开项目
7)右键单击Project Name并选择Groovy Tools - >刷新依赖关系

现在,也许您不必跳过所有这些循环来获取Refresh Dependencies工作,但这就是我所做的。如果我只是做#7,而不先做其他的东西,它不适用于这个版本的GGTS。现在,WAR会在服务器上正确生成并部署。


Using: GG ver 2.2.4; and Groovy/Grails Tool Suite Version: 3.3.0.RELEASE

Here's the question: How do I get a specific Grails JAR into the WAR built with GGTS?

As side questions, why doesn't the WAR get that JAR packaged into it? And why does "grails run-app" work just fine, but deploying the WAR (in Development or Production) fails?

Here's the background:

When I run "grails run-war" locally on my Windows 7 deveopement computer, it fails with:

2013-10-16 11:36:05,371 [localhost-startStop-1] ERROR context.ContextLoader  - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'grailsApplication' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: grails/test/mixin/domain/DomainClassUnitTestMixin
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)
**Caused by: java.lang.NoClassDefFoundError: grails/test/mixin/domain/DomainClassUnitTestMixin**

When I run "grails war" and then deploy the Production WAR to Tomcat 6 on my server, I get a similar deployment error inside catalina.out:

INFO   | jvm 1    | 2013/10/16 17:03:47 | Oct 16, 2013 5:03:47 PM org.apache.catalina.core.ApplicationContext log
INFO   | jvm 1    | 2013/10/16 17:03:47 | INFO: HTMLManager: start: Starting web application at '/TSWeb-0.1'
INFO   | jvm 1    | 2013/10/16 17:03:48 | Oct 16, 2013 5:03:48 PM org.apache.catalina.core.ApplicationContext log
INFO   | jvm 1    | 2013/10/16 17:03:48 | INFO: Initializing Spring root WebApplicationContext
INFO   | jvm 1    | 2013/10/16 17:03:49 | 2013-10-16 17:03:49,388 [TP-Processor2] ERROR context.ContextLoader  - Context initialization failed
INFO   | jvm 1    | 2013/10/16 17:03:49 | org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'grailsApplication' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: grails/test/mixin/support/GrailsUnitTestMixin
INFO   | jvm 1    | 2013/10/16 17:03:49 |   at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
INFO   | jvm 1    | 2013/10/16 17:03:49 |   at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:311)
INFO   | jvm 1    | 2013/10/16 17:03:49 |   at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:776)
INFO   | jvm 1    | 2013/10/16 17:03:49 |   at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:705)
INFO   | jvm 1    | 2013/10/16 17:03:49 |   at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:898)
INFO   | jvm 1    | 2013/10/16 17:03:49 |   at java.lang.Thread.run(Thread.java:724)
INFO   | jvm 1    | 2013/10/16 17:03:49 | **Caused by: java.lang.NoClassDefFoundError: grails/test/mixin/support/GrailsUnitTestMixin**
INFO   | jvm 1    | 2013/10/16 17:03:49 |   at java.lang.Class.forName(Class.java:270)

I can explore inside the WAR, and see that WEB-INF/lib/ does NOT contain the JAR in which both of the above classes reside (grails-plugin-testing-2.2.4.jar).

I tried putting

grails.war.dependencies = [
    "grails-plugin-testing-2.2.4.jar"
    ]

into config.groovy and this did not work. The WAR still did not contain that JAR and I got the same error.

So, I just put grails-plugin-testing-2.2.4.jar into the WEB-INF/lib folder on the server and re-deployed and verified that the error above goes away, but now I get another error on the server:

INFO   | jvm 1    | 2013/10/16 18:34:02 | Oct 16, 2013 6:34:02 PM org.apache.catalina.core.ApplicationContext log
INFO   | jvm 1    | 2013/10/16 18:34:02 | INFO: HTMLManager: start: Starting web application at '/TSWeb-0.1'
INFO   | jvm 1    | 2013/10/16 18:34:03 | Oct 16, 2013 6:34:03 PM org.apache.catalina.core.ApplicationContext log
INFO   | jvm 1    | 2013/10/16 18:34:03 | INFO: Initializing Spring root WebApplicationContext
INFO   | jvm 1    | 2013/10/16 18:34:07 | 2013-10-16 18:34:07,011 [TP-Processor12] ERROR context.ContextLoader  - Context initialization failed
INFO   | jvm 1    | 2013/10/16 18:34:07 | org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.RuntimeException: Unable to locate constructor with Class parameter for class org.codehaus.groovy.grails.commons.DefaultGrailsBootstrapClass
INFO   | jvm 1    | 2013/10/16 18:34:07 |   at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
INFO   | jvm 1    | 2013/10/16 18:34:07 |   at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:311)
INFO   | jvm 1    | 2013/10/16 18:34:07 |   at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:776)
INFO   | jvm 1    | 2013/10/16 18:34:07 |   at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:705)
INFO   | jvm 1    | 2013/10/16 18:34:07 |   at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:898)
INFO   | jvm 1    | 2013/10/16 18:34:07 |   at java.lang.Thread.run(Thread.java:724)
INFO   | jvm 1    | 2013/10/16 18:34:07 | Caused by: java.lang.RuntimeException: Unable to locate constructor with Class parameter for class org.codehaus.groovy.grails.commons.DefaultGrailsBootstrapClass
INFO   | jvm 1    | 2013/10/16 18:34:07 |   ... 6 more
INFO   | jvm 1    | 2013/10/16 18:34:07 | Caused by: java.lang.reflect.InvocationTargetException
INFO   | jvm 1    | 2013/10/16 18:34:07 |   ... 6 more
INFO   | jvm 1    | 2013/10/16 18:34:07 | Caused by: java.lang.NoClassDefFoundError: grails/test/GrailsMock
INFO   | jvm 1    | 2013/10/16 18:34:07 |   at java.lang.Class.privateGetDeclaredMethods(Class.java:2521)
INFO   | jvm 1    | 2013/10/16 18:34:07 |   at java.lang.Class.getDeclaredMethods(Class.java:1845)
INFO   | jvm 1    | 2013/10/16 18:34:07 |   ... 6 more
INFO   | jvm 1    | 2013/10/16 18:34:07 | Caused by: java.lang.ClassNotFoundException: grails.test.GrailsMock
INFO   | jvm 1    | 2013/10/16 18:34:07 |   ... 8 more

I'll investigate the second error and ask about it in a different question and reference it here. [UPDATE: This error goes away if I also put grails-test-2.2.4.jar into WEB-INF/lib on the server. Then, the WAR deploys and runs successfully.]

To keep this Question/Answer to one topic, how do I get these 2 JARs into the WAR?

But, of course, perhaps there is ONE solution that would solve BOTH issues (he-he-he - not likely but worth mentioning!) For example, I am ignorant as to why grails-plugin-testing-2.2.4.jar is used. Perhaps there is a setting I need to change to have that "go away."

THANKS!

OK - figured it out - enough to make it work....

[Still bamboozled as to why GG didn't pick up those JARs all on its own.]

To figure out which JAR files contained the classes that were reported missing during WAR deployment, I just did a hunt and peck in the dist folder containing grails JARs where Groovy/Grails v2.2.4 was installed (C:\grails-2.2.4\dist). I used 7zip to just browse the JARs. Since both classes had the word "test" in them, I looked first in JARS with "test" in the name and found them easily. That's how I figured out the two JAR files that I listed above in the question that contained those classes.

Putting them in the WEB-INF/lib folder on the server and then having a successful start/deployment of the project confirmed that having them in the WAR would fix the issue.

To get them into the Project and thus the WAR when it's created, I did this...

1) run "grails clean" on the project in question
2) close the project (and all others)
3) exit g&g tool suite
4) drag the jar file to your "PROJECTNAME/lib" directory for your project using Windows Explorer.
5) start g&g tool suite
6) open the project
7) right-click on the Project Name and choose Groovy Tools -> Refresh Dependencies

Now, maybe you don't have to jump thru ALL those hoops to get Refresh Dependencies to work, but that's what I did. If I JUST do #7, without doing the other stuff first, it does not work on this version of GGTS. Now, the WAR generates and deploys correctly on the server.