Using a War Dependency in Maven

June 14th 2019 Maven

To take full advantage of TypeScript in the Vue.js-based Hippo CMS-hosted SPA I'm working on, I configured the typescript-generator-maven-plugin to generate TypeScript interfaces for Java classes used in REST services. It worked great with classes originating from external libraries which I could add as dependencies. However, it failed with classes originating from the Hippo CMS Site module because it was compiled into a .war archive which Maven can't handle as a dependency.

I tried adding the CMS Site module like any other .jar archive:

<dependency>
  <groupId>com.damirscorner.blog.samples</groupId>
  <artifactId>maven-war-dependency-site</artifactId>
  <version>${project.version}</version>
</dependency>

But the build failed with a rather clear although not very helpful error message:

[ERROR] Failed to execute goal on project maven-war-dependency-vue-app: Could not resolve dependencies for project com.damirscorner.blog.samples:maven-war-dependency-vue-app:pom:0.1.0-SNAPSHOT: Could not find artifact com.damirscorner.blog.samples:maven-war-dependency-site:jar:0.1.0-SNAPSHOT in hippo (https://maven.onehippo.com/maven2/) -> [Help 1]

I had no idea how to solve the problem until I stumbled upon a StackOverflow answer with a snippet that used maven-war-plugin to generate an additional artifact with classes which can be referenced from other modules.

This feature made it really easy to fix my issue:

  • First, I had to add the maven-war-plugin to the CMS Site module to generate the additional artifact:

    <plugin>
      <artifactId>maven-war-plugin</artifactId>
      <version>3.2.2</version>
      <configuration>
        <attachClasses>true</attachClasses>
      </configuration>
    </plugin>
    
  • Then I could modify the dependency in the SPA module to use the new artifact instead of the .war archive (by adding the classes modifier):

    <dependency>
      <groupId>com.damirscorner.blog.samples</groupId>
      <artifactId>maven-war-dependency-site</artifactId>
      <version>${project.version}</version>
      <classifier>classes</classifier>
    </dependency>
    

I couldn't believe how simple the final solution was. However, I'm not sure I'd ever find it, if it wasn't for that random StackOverflow answer.

Copyright
Creative Commons License