Intellij IDEA artifact 'XXXX:war exploded' has invalid extension
Asked Answered
V

4

23

Every time I make even the tiniest change to my POM Intellij removes the .war extension for my exploded artifact in the Project Structure output directory setting. This causes an error in Intellij's Run/Debug configuration:

Artifact 'XXXX:war exploded' has invalid extension.

In order to resolve the issue I must manually override the Project Structure output directory setting. Every time I make even the tiniest change to the POM I must go back to the Output directory setting and manually append ".war" to the end of the Output directory setting. This is getting very old and frustrating.

e.g. I must change this:

E:\workarea\enterp\application\target\application

to this:

E:\workarea\enterp\application\target\application.war

If I manually set the Maven WAR plugin outputDirectory configuration as follows, this does not help at all:

<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>${maven.war.plugin.version}</version>
    <configuration>

        <!-- Output directory of artifact:war exploded keeps losing the .war extension -->
        <outputDirectory>${project.build.directory}.war</outputDirectory>

    </configuration>
</plugin>

How can I resolve this problem?

EDIT:

Here's the complete build config:

    <build>
    <!-- Maven will append the version to the finalName (which is the name
        given to the generated war, and hence the context root) -->
    <finalName>${project.artifactId}</finalName>

    <plugins>
        <!-- Compiler plugin enforces Java 1.6 compatibility and activates annotation
            processors -->
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler.plugin.version}</version>
            <configuration>
                <source>${maven.compiler.source}</source>
                <target>${maven.compiler.target}</target>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>${maven.war.plugin.version}</version>
            <configuration>
                <!-- Output directory of artifact:war exploded keeps losing the .war extension -->
                <outputDirectory>${project.build.directory}/${project.artifactId}.war</outputDirectory>

                <!-- Java EE 7 doesn't require web.xml, Maven needs to catch up! -->
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>
        <!-- The WildFly plugin deploys your war to a local WildFly container -->
        <!-- To use, run: mvn package wildfly:deploy -->
        <plugin>
            <groupId>org.wildfly.plugins</groupId>
            <artifactId>wildfly-maven-plugin</artifactId>
            <version>${version.wildfly.maven.plugin}</version>
        </plugin>
    </plugins>

</build>

SECOND EDIT:

I discovered that one solution is to append ".war" to ${project.artifactId} in the build configuration, e.g.:

<finalName>${project.artifactId}.war</finalName>

and remove outputDirectory from the plugin configuration. So the build config should look like this:

<build>
    <!--
        Maven will make finalName the name of the generated war.

        NOTE:   Output directory of artifact:war exploded keeps losing the .war extension
                http://youtrack.jetbrains.com/issue/IDEA-86484
                http://youtrack.jetbrains.com/issue/IDEA-95162

                The solution is to append ".war" to ${project.artifactId}, below:
    -->
    <finalName>${project.artifactId}.war</finalName>

    <plugins>
        <!-- Compiler plugin enforces Java 1.6 compatibility and activates annotation
            processors -->
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler.plugin.version}</version>
            <configuration>
                <source>${maven.compiler.source}</source>
                <target>${maven.compiler.target}</target>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>${maven.war.plugin.version}</version>
            <configuration>
                <!-- Java EE 7 doesn't require web.xml, Maven needs to catch up! -->
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>
        <!-- The WildFly plugin deploys your war to a local WildFly container -->
        <!-- To use, run: mvn package wildfly:deploy -->
        <plugin>
            <groupId>org.wildfly.plugins</groupId>
            <artifactId>wildfly-maven-plugin</artifactId>
            <version>${version.wildfly.maven.plugin}</version>
        </plugin>
    </plugins>

</build>

DISCLAIMER: If you use this workaround just be aware that when you deploy an unexploded WAR artifact the file name will be named XXXX.war.war. It works -- I deployed the artifact as a WAR file in Intellij -- but it's ugly.

INFO [org.jboss.as.server.deployment] (MSC service thread 1-7) JBAS015876: Starting deployment of "XXXX.war.war" (runtime-name: "XXXX.war.war)"

If someone can tell me how to configure the Intellij project to work with Maven to select one or the other finalName values depending on whether I'm deploying a WAR file vs. exploded artifact then this question will be sufficiently answered.

<!-- Exploded artifact --> 
<finalName>${project.artifactId}.war</finalName>

<!-- WAR file (unexploded) artifact --> 
<finalName>${project.artifactId}</finalName>
Veer answered 13/7, 2014 at 18:1 Comment(1)
Why are you changing the finalName in the pom.xml? Are you doing that to work around this bug, or for some other reason related to your development/deployment workflow?Heartwood
H
37

There's a way to fix this in IntelliJ, without changing your pom.xml file(s), by adding an artifact with a reference to the exploded war (or in my case, the exploded ear) and it won't get stomped every time IntelliJ re-imports the maven pom(s). Here's how:

  1. Stop/undeploy your current artifact deployment

  2. Edit your run config, and in the Deployment tab, remove the current exploded war/ear artifact

  3. Open the project's Artifacts settings and add a new artifact Add new artifact

  4. Use the plus button to add a new war or (in my case) ear exploded artifact Add new war or ear exploded artifact

  5. Give it a name, then edit the Output directory to add the appropriate extension (.war or .ear) Rename output directory to add extension

  6. In the Output Layout section where you see <output root>, use the plus button to add an Artifact Add new artifact in output layout

  7. Select the desired exploded artifact Select the desired exploded artifact

  8. Edit your run config again, and in the Deployment tab, add the new workaround exploded artifact Deploy new artifact in run configuration

Thanks to Nikolay Chashnikov for describing this in his comment on the bug report

Heartwood answered 23/12, 2014 at 0:28 Comment(2)
When using Maven (modify step 5 above) move the IDEA -> Project Structure -> ear:ear exploded -> Output directory, down a level. This is because Maven clean/package expects the target\groupId.artifactId-version.ear to always be a file. So in IDEA set something like "C:\Project\ear\target\idea\groupId.artifactId-version.ear" note the addition of "\idea\" in the path as well as .ear suffix to the directory name, now no conflict with simultaneous maven clean/package cycles.Knucklehead
This is by far the easiest and safest solution. Thanks, Alex!Gulley
R
4

Actually, you should leave the finalName attribute alone, otherwise you'll get the problems you describe. Rather, you should change the config for the maven war plugin to use the webappDirectory like this:

<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
        <webappDirectory>${project.build.directory}/${project.artifactId}.${project.packaging}</webappDirectory>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
</plugin>
Rapine answered 15/7, 2014 at 19:38 Comment(3)
If this was the solution it would be a very poor solution because if I choose to deploy using the non-exploded WAR artifact then I do not want to deploy to ${project.build.directory}.war. However, I attempted to use this configuration setting to see if it would make a difference. It did not. The problem for WAR exploded artifact did not go away.Veer
Fyi the Intellij bug report is here.Veer
this configuration worked for me. I guess profiles can be used to change the directory according to needs to overcome @PatrickGarner 's concernsCogitative
P
3

If we are talking about WAR inside EAR there is another way to resolve your problem by using correct configuration inside maven-ear-plugin. WAR pom.xml should be left as is, without any changes, but EAR pom.xml should contains something like this. (please, pay your attention to <unpack>${unpack.wars}</unpack>)

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-ear-plugin</artifactId>
    <version>2.9</version>
    <configuration>
        <version>6</version>
        <defaultLibBundleDir>lib</defaultLibBundleDir>
        <generateApplicationXml>false</generateApplicationXml>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
            </manifest>
        </archive>
        <modules>
            <webModule>
                <groupId>com.test.app</groupId>
                <artifactId>test-app-war</artifactId>
                <unpack>${unpack.wars}</unpack>
            </webModule>
        </modules>
    </configuration>
</plugin>

and then you can add profiles default and debug for proper artifact assembling.

<profiles>
        <profile>
            <id>default</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <unpack.wars>false</unpack.wars>
            </properties>
        </profile>
        <profile>
            <id>debug</id>
            <activation>
                <property>
                    <name>debug</name>
                </property>
            </activation>
            <properties>
                <unpack.wars>true</unpack.wars>
            </properties>
        </profile>
</profiles> 

use debug profile inside IntelliJ IDEA for expanding wars and default profile for building artifacts in command line or CI (default profile would be active if no profile were provided, so your build will works as previously).

Maven Projects view

With this solution HotSwap and resources updates works as expected.

Hope this helps.

Peacetime answered 6/10, 2015 at 9:21 Comment(0)
B
-1

I think it's the same as this question: IntelliJ Artifact has invalid extension

Add a .war extension to the output directory as shown in my answer: https://mcmap.net/q/585044/-intellij-artifact-has-invalid-extension

Beach answered 29/8, 2014 at 13:28 Comment(1)
The problem is that Project Structure keeps losing the .war extension added to output directory name every time the POM is edited. It's a bug. Check my earlier answer to that question.Veer

© 2022 - 2024 — McMap. All rights reserved.