Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

The Recipe for Angular 2 in a Java EE Environment: Maven Build

DZone's Guide to

The Recipe for Angular 2 in a Java EE Environment: Maven Build

In the last installment in this series, we take what we've learned about Java EE and Angular to create a Maven Build. Read on for more!

· Web Dev Zone
Free Resource

Add user login and MFA to your next project in minutes. Create a free Okta developer account, drop in one of our SDKs to your application and get back to building.

This is the fifth article in our "The Recipe for Angular 2 in a Java EE Environment" series, with a more detailed description of the build of the Angular2 and JavaEE Project. It follows my fourth article about Angular 2 and Java EE that gave a detailed overview of the Frontend infrastructure of the Car Rental Project.

Motivation

In this article, the build of the project is covered. That might not be considered the fun stuff, but to get Angular approved in a corporate environment you will have to learn to integrate with the existing Continuous Integration Infrastructure. The Deployment and Testing requirements also need to be met. This article should give you an example of how this could be done. 

Project

The project is based on a wildfly-archetype. The archetype wildfly-javaee7-webapp-ear-archetype was the skeleton to start from. It is a Maven Multi Module project with ear, ejb, and web module that builds an ear. 

This article will show you how to create a web module build for Angular with Angular-CLI and how to build Docker Images for testing in the Ear Module.

Web Module Build

The build is in the pom.xml. The Angular CLI setup is done according to the documentation of Angular CLI.

The build is a 6 step process:

1. Delete the dist and node_modules directories in the src directories. This is done to clean up for a local build where the directories might exist.

<plugin>
    <artifactId>maven-clean-plugin</artifactId>
    <configuration>
      <failOnError>false</failOnError>
      <filesets>
          <fileset>
              <directory>src/main/angular2/carrental</directory>
              <includes>
                  <include>dist/**/*.*</include>
                  <include>node_modules/**/*.*</include>
              </includes>
              <followSymlinks>false</followSymlinks>
          </fileset>
      </filesets>
    </configuration>
</plugin>

2. Copy the Angular UI sources to target/Angular2 to build it in target.

<plugin>
  <artifactId>maven-resources-plugin</artifactId>
  <executions>
    <execution>
      <id>copy-angular2-dir</id>
      <phase>validate</phase>
      <goals>
        <goal>copy-resources</goal>
      </goals>
      <configuration>
        <outputDirectory>${basedir}/target/angular2</outputDirectory>
        <resources>
          <resource>
            <directory>src/main/angular2</directory>
            <includes>
              <include>carrental/**/*.*</include>
            </includes>
          </resource>
        </resources>
      </configuration>
    </execution>
  </executions>
</plugin>

3. Call npm install to resolve the dependencies of the Angular UI in package.json. This step takes the most time in the build. To run the build in a CI environment you should have some kind of local npm cache server and a proxy setup on the CI server.

<plugin>
  <artifactId>exec-maven-plugin</artifactId>
  <groupId>org.codehaus.mojo</groupId>
  <version>1.4.0</version>
  <executions>
    <execution>
      <id>npm install</id>
      <goals>
        <goal>exec</goal>
      </goals>
      <phase>generate-sources</phase>
      <configuration>
        <executable>npm</executable>
        <arguments>
          <argument>install</argument>
        </arguments>
        <workingDirectory>${basedir}/target/angular2/carrental</workingDirectory>
        <target>
          <echo message="Npm install" />
        </target>
      </configuration>
    </execution>
  </executions>
</plugin>

4. Build the Angular UI with Angular CLI. There is a Unix and a Windows profile. The Unix build is for all Unix-like Operating Systems and the CI Server. The Windows build is for local builds and requires a local Angular CLI installation. 

<plugin>
  <artifactId>exec-maven-plugin</artifactId>
  <groupId>org.codehaus.mojo</groupId>
  <version>1.4.0</version>
  <executions>
    <execution>
      <id>angular-cli build</id>
      <goals>
        <goal>exec</goal>
      </goals>
      <phase>generate-resources</phase>
      <configuration>
        <executable>node_modules/@angular/cli/bin/ng</executable>
        <arguments>
          <argument>build</argument>
          <argument>--prod</argument>
          <argument>--bh</argument>
          <argument>/carrental-web/</argument>
        </arguments>
        <workingDirectory>${basedir}/target/angular2/carrental</workingDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

In Line 13, ng is called out of the dependencies that were resolved by the npm install step. That means no Angular CLI install on the Computer is needed. 

In Line 16, --prod is used to get an optimized build with treeshaking.

Lines 17-18 are used to set the base-href for the routing. 

5. Run the Angular UI Tests on PhantomJS. If the test fails the build breaks.

<plugin>
  <artifactId>exec-maven-plugin</artifactId>
  <groupId>org.codehaus.mojo</groupId>
  <version>1.4.0</version>
  <executions>
    <execution>
      <id>angular-cli test</id>
      <goals>
        <goal>exec</goal>
      </goals>
      <phase>test</phase>
      <configuration>
        <executable>node_modules/@angular/cli/bin/ng</executable>
        <arguments>
          <argument>test</argument>
          <argument>--browsers</argument>
          <argument>PhantomJS</argument>
          <argument>--reporters</argument>
          <argument>junit</argument>
          <argument>--single-run</argument>
        </arguments>
        <workingDirectory>${basedir}/target/angular2/carrental</workingDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

In Lines 16-17, we use PhantomJS to determine the browser on which we want to run the tests.

In Lines 18-20, the JUnit reporter for Karma is set with the --single-run parameter. That executes the tests once and gives back the results in JUnit format to break the build if the tests fail. The test has to be compiled to ES 5 to work on PhantomJS.

Step 6 is to build the war.

<plugin>
  <artifactId>maven-war-plugin</artifactId>
  <version>${version.war.plugin}</version>
  <configuration>
    <!-- Java EE 7 doesn't require web.xml, Maven needs to catch up! -->
    <failOnMissingWebXml>false</failOnMissingWebXml>
    <webResources>
      <resource>
        <directory>${basedir}/target/angular2/carrental/dist</directory>
        <includes>
          <include>assets/**/*.*</include>
          <include>*.*</include>
        </includes>
      </resource>
      <resource>
        <directory>${basedir}/target/angular2/carrental/src</directory>
        <includes>
          <include>locale/*.xlf</include>
        </includes>
      </resource>
      <resource>
        <directory>src/main/webapp</directory>
      </resource>
    </webResources>
  </configuration>
</plugin>


Ear Module Build

The build is in the pom.xml of the Ear Module. It has 2 Profiles to build a Wildfly Docker image and to build a Websphere Liberty image. To build the Images the docker-maven-plugin of fabrik8.io is used. To build the Ear, 'mvn clean install' can be used. To build the Docker Image, the Docker Service has to be running and 'mvn clean docker:build' can be used. To start and stop you can use 'mvn docker:start' and mvn docker:stop'

The Profile to build the Wildfly Image.

<profile>
  <id>prodDockerWildfly</id>
  <activation>
    <activeByDefault>true</activeByDefault>
  </activation>
  <build>
    <plugins>
      <plugin>
        <groupId>io.fabric8</groupId>
        <artifactId>docker-maven-plugin</artifactId>
        <configuration>
          <images>
            <image>
              <alias>carrental</alias>
              <name>carrental:${project.version}</name>
              <build>
                <dockerFile>${project.basedir}/Dockerfile</dockerFile>
                <ports>
                  <port>8080</port>
                </ports>
              </build>

              <run>
                <ports>
                  <port>8080:8080</port>
                </ports>
                <log>
                  <enabled>true</enabled>
                  <prefix>Wildfly</prefix>
                </log>
                <wait>
                  <http>
                    <url>http://localhost:8080/carrental-web/</url>
                  </http>
                  <time>30000</time>
                </wait>
              </run>
            </image>
          </images>
        </configuration>
      </plugin>
    </plugins>
  </build>
</profile>

Line 15 sets the name of the Docker Image, which is based on the Project Version, to have different Images for the Versions.

Lines 16-21 set the Dockerfile we will use, and that the Port Wildfly runs on.

Lines 23-37 maps the Image Port to the exported port. It enables us to log for Wildfly and it sets a maximum wait time of 30 seconds for the Image reply to a request.

The Dockerfile for Wildfly

The Dockerfile is based on the images provided by airhacks for Wildfly. There is one for the Websphere Liberty too.

FROM airhacks/wildfly-ping
MAINTAINER Sven Loesekann
COPY ./target/carrental-ear.ear ${DEPLOYMENT_DIR}


Conclusion

That is a solution to build an Angular UI with Angular CLI in a Java EE CI environment. The Maven build can have tests for Angular and Java and fails on error. The Ear can be tested with the Docker Images that can be built in the process. This was the final bit to make Angular usable in a corporate Java EE environment. I hope some Java Devs have become interested in Angular, as I think Angular has a bright future in corporate Java EE environments. This is the end of this series of articles. The project will continue to be improved. The Project Diary will give you the information.

Launch your application faster with Okta’s user management API. Register today for the free forever developer edition!

Topics:
java ee ,angular 2 ,angular cli ,maven ,web dev

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}