2
votes

Prior to Grails 2.2.x I have been able to create grails projects with Maven and include them in a Maven Ear project with everything working just fine. The new pom.xml in Grails 2.2.x has changed the packaging type to "grails-app" and this is causing some new issues. The old packaging type was "war" and that worked fine.

Has anyone run into the same issue? Is there a workaround?

This is the structure of my project.

TestProject 
 |-pom.xml 
 |-TestEar 
 |  \pom.xml 
 |-TestGrailsApp 
    \pom.xml 

TestProject pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd";> 
  <modelVersion>4.0.0</modelVersion> 
  <groupId>test</groupId> 
  <artifactId>testProject</artifactId> 
  <version>0.1-SNAPSHOT</version> 
  <packaging>pom</packaging> 
  <name>Test Project</name> 
    <modules> 
        <module>TestGrailsApp</module> 
        <module>TestEar</module> 
    </modules> 
</project>

TestGrailsApp pom.xml


4.0.0 test testGrailsApp grails-app 0.1-SNAPSHOT Test Grails App

<parent> 
  <groupId>test</groupId> 
  <artifactId>testProject</artifactId> 
  <version>0.1-SNAPSHOT</version> 
</parent> 

<properties> 
    <grails.version>2.2.1</grails.version> 
</properties> 

...

TestEar pom.xml


<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd";> 
    <modelVersion>4.0.0</modelVersion> 
    <artifactId>testEar</artifactId> 
    <packaging>ear</packaging> 
    <name>Test Ear</name> 
    <parent> 
        <groupId>test</groupId> 
        <artifactId>testProject</artifactId> 
        <version>0.1-SNAPSHOT</version> 
    </parent> 
    <build> 
        <plugins> 
            <plugin> 
                <artifactId>maven-ear-plugin</artifactId> 
                <configuration> 
                    <archive> 
                        <manifest> 
                            <addClasspath>true</addClasspath> 
                        </manifest> 
                    </archive> 
                    <modules> 
                        <webModule> 
                            <groupId>test</groupId> 
                            <artifactId>testGrailsApp</artifactId> 
                            <contextRoot>/web</contextRoot> 
                        </webModule> 
                    </modules> 
                </configuration> 
            </plugin> 
        </plugins> 
    </build> 
    <dependencies> 
        <dependency> 
            <groupId>test</groupId> 
            <artifactId>testGrailsApp</artifactId> 
            <type>grails-app</type> 
            <version>0.1-SNAPSHOT</version> 
        </dependency> 
    </dependencies> 
</project> 

This is the result of trying to build the project

$ mvn install -e 

Error stacktraces are turned on.

[INFO] Scanning for projects... 
[INFO] Reactor build order: 
[INFO]   TestProject 
[INFO]   TestGrailsApp 
[INFO]   TestEar 
[INFO] ------------------------------------------------------------------------ 
[INFO] Building TestProject 
[INFO]    task-segment: [install] 
[INFO] ------------------------------------------------------------------------ 
[INFO] [timestamp:create {execution: default}] 
[INFO] [site:attach-descriptor {execution: default-attach-descriptor}] 
[INFO] [install:install {execution: default-install}] 
[INFO] Installing /local2/testProject/pom.xml to /usr2/User1/.m2/repository/test/TestProject/0.1-SNAPSHOT/testProject-0.1-SNAPSHOT.pom 
[INFO] ------------------------------------------------------------------------ 
[INFO] Building TestGrailsApp 
[INFO]    task-segment: [install] 
[INFO] ------------------------------------------------------------------------ 
[INFO] [grails:validate {execution: default-validate}] 
[INFO] [timestamp:create {execution: default}] 
[INFO] [grails:init {execution: default-init}] 
[INFO] [grails:config-directories {execution: default-config-directories}] 
[INFO] [grails:maven-compile {execution: default-maven-compile}] 

|Loading Grails 2.2.1 
|Downloading: testGrailsApp-0.1-SNAPSHOT.pom 
|Configuring classpath 
|Running pre-compiled script 
. 
|Environment set to development 
........... 
[INFO] [grails:maven-test {execution: default-maven-test}] 

|Loading Grails 2.2.1 
|Configuring classpath 
|Running pre-compiled script 
. 
|Environment set to test 
.................... 
|Running 4 unit tests... 

|Running 4 unit tests... 1 of 4 

|Running 4 unit tests... 2 of 4 

|Running 4 unit tests... 3 of 4 

|Running 4 unit tests... 4 of 4 
|Completed 4 unit tests, 0 failed in 1787ms 
. 
|Tests PASSED - view reports in /local2/testProject/testGrailsApp/target/test-reports 
[INFO] [grails:maven-grails-app-war {execution: default-maven-grails-app-war}] 

|Loading Grails 2.2.1 
|Configuring classpath 
|Running pre-compiled script 
. 
|Environment set to prod 
................................. 
|Packaging Grails application 
................ 
|Compiling 3 GSP files for package [testGrailsApp] 
... 
|Building WAR file 
...................................... 
|Done creating WAR target/testGrailsApp-0.1-SNAPSHOT.war 
[INFO] [grails:maven-functional-test {execution: default-maven-functional-test}] 

|Loading Grails 2.2.1 
|Configuring classpath 
|Running pre-compiled script 
. 
|Environment set to test 
.................... 
|Running 4 unit tests... 

|Running 4 unit tests... 1 of 4 

|Running 4 unit tests... 2 of 4 

|Running 4 unit tests... 3 of 4 

|Running 4 unit tests... 4 of 4 
|Completed 4 unit tests, 0 failed in 1747ms 
............................ 
|Packaging Grails application 
........................... 
|Tests PASSED - view reports in /local2/testProject/testGrailsApp//target/test-reports 
[INFO] [install:install {execution: default-install}] 
[INFO] Installing /local2/testProject/testGrailsApp/target/testGrailsApp-0.1-SNAPSHOT.war to /usr2/User1/.m2/repository/testProject/testGrailsApp/0.1-SNAPSHOT/testGrailsApp-0.1-SNAPSHOT.war 
[INFO] ------------------------------------------------------------------------ 
[INFO] Building TestEar 
[INFO]    task-segment: [install] 
[INFO] ------------------------------------------------------------------------ 
[INFO] [ear:generate-application-xml {execution: default-generate-application-xml}] 
[INFO] ------------------------------------------------------------------------ 
[ERROR] BUILD FAILURE 
[INFO] ------------------------------------------------------------------------ 
[INFO] Artifact[war:testProject:testGrailsApp] is not a dependency of the project. 
[INFO] ------------------------------------------------------------------------ 
[INFO] Trace 
org.apache.maven.BuildFailureException: Artifact[war:testProject:testGrailsApp] is not a dependency of the project. 
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:715) 
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:556) 
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:535) 
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387) 
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348) 
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180) 
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328) 
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138) 
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:362) 
    at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315) 
    at org.codehaus.classworlds.Launcher.launch(Launcher.java:255) 
    at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430) 
    at org.codehaus.classworlds.Launcher.main(Launcher.java:375) 
Caused by: org.apache.maven.plugin.MojoFailureException: Artifact[war:testProject:testGrailsApp] is not a dependency of the project. 
    at org.apache.maven.plugin.ear.AbstractEarModule.resolveArtifact(AbstractEarModule.java:114) 
    at org.apache.maven.plugin.ear.WebModule.resolveArtifact(WebModule.java:78) 
    at org.apache.maven.plugin.ear.AbstractEarMojo.execute(AbstractEarMojo.java:200) 
    at org.apache.maven.plugin.ear.GenerateApplicationXmlMojo.execute(GenerateApplicationXmlMojo.java:84) 
    at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490) 
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694) 
    ... 17 more 
[INFO] ------------------------------------------------------------------------ 
[INFO] Total time: 51 seconds 
[INFO] Finished at: Wed Mar 27 11:20:40 PDT 2013 
[INFO] Final Memory: 39M/315M 
[INFO] ------------------------------------------------------------------------ 
2

2 Answers

2
votes

To make this work you can republish your grails application as a war artifact. To do this in the Grails application pom add the following. Then reference the new war artifact in your EAR pom.

<project>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>testGrailsApp</artifactId>
    <packaging>grails-app</packaging>

    <parent>
        <artifactId>testProject</artifactId>
        <groupId>test</groupId>
        <version>0.1-SNAPSHOT</version>
    </parent>

    <properties>
        <grails.version>2.2.1</grails.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
                <executions>
                    <execution>
                        <id>create-war-pom</id>
                        <phase>install</phase>
                        <goals>
                            <goal>install-file</goal>
                        </goals>
                        <configuration>
                            <artifactId>${project.parent.artifactId}War</artifactId>
                            <groupId>${groupId}</groupId>
                            <version>${version}</version>
                            <file>${build.directory}/${artifactId}-${version}.war</file>
                            <generatePom>true</generatePom>
                            <packaging>war</packaging>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
0
votes

I think you only need two simple modifications:

  1. TestGrailsApp pom.xml Add the artifact information of the app after inheriting from parent pom

    <parent> 
       <groupId>test</groupId> 
       <artifactId>testProject</artifactId> 
       <version>0.1-SNAPSHOT</version> 
    </parent>
    
    <groupId>test</groupId>
    <artifactId>testGrailsApp</artifactId>
    <packaging>grails-app</packaging>
    <version>0.1</version>
    <name>testGrailsApp</name>
    <description>testGrailsApp</description>
    
    <properties>
       <grails.version>2.2.1</grails.version>
    </properties>
    
  2. Edit TestEar pom.xml as below (add the type as war instead of grails-app)

    <dependencies> 
        <dependency> 
            <groupId>test</groupId> 
            <artifactId>testGrailsApp</artifactId> 
            <version>0.1-SNAPSHOT</version>
            <type>war</type>            
        </dependency> 
    </dependencies>
    

You are done.!!

Note: I executed "grails create-pom test" to create the app's pom.xml

Reason: TestProject(Parent) -- TestGrailsApp (Child) -- TestEar (Child)

Grails maven plugin implicitly builds war in the lifecycle. once the war file is built all you need to inform the ear pom to grab the war and use it to package it in ear. Maven-ear-plugin does the rest.