Setup a single Angular 6 and Spring Boot project with Maven

Angular and Spring Boot are both great frameworks which are nowadays in combination especially by java developers gladly used.

In this article I want to show therefore how you can setup a parent maven project which includes an angular and spring boot child, which can finally be deployed on a tomcat server. All this is made in Intellij IDEA (of course this can be done in any other IDE :-))

Prerequisites

Because I want only to focus on the creation of the project, the current version angular cli tomcat server (or any other deploy evnironment) have already to be installed. In this example the following versions are used:

  • Angular CLI 6.1.5
  • Tomcat 9.0
  • IntelliJ IDEA 2017.2.5

What we’re going to do

Principally our aim is to setup a project which has the following structure, which contains a parent module and two child-modules in which once represents the angular part (frontend) and the otherone the spring boot part (backend)

Create parent

(File > New Project)

Before we can actually begin with the main content of our project (the angular and spring part), we create a new Web Application (to build the .war file). Afterwards we will found the folder “web” with the common WEB-INF subfolder. Because the whole thing should be a maven project we add whithout further ado the framework support, by making a right-click on the parent module and select “Add Framework Support”

(Right-click on paren module > ”Add Framework Support” > Select “Maven”)

For clarity it would be helpful to change the tag groupId , in the pom.xml, to a more meaninful content e. g “com.tutorial”.

Add Angular 6 part

The approach I chose is to add this part to the parent is to create first of all a new module and subsequent a new angular project inside of it. The general creation of the Maven module is easily done by the following way.

(Right-click on paren module > New > Module > Maven)

Now you will see, that in the pom.xml file of the parent module a new tag has been created, which shows, that it has a relation to a child.

<?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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tutorial</groupId>
<artifactId>medium_parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>frontend</module>
</modules>

</project>

Create Angular project

Open a terminal in the frontend module (in the direcory frontend/src/main) and execute the following command, which will create a new subfolder called “web” without a git repository and the application name “frontendApp”.

ng new --skip-git --directory web frontendApp

Now we need maven to tell how the angular app should be handled when starting the build. For this we add the following part in to the project tag of the frontent pom.xml, which will advise maven to install all npm dependencies and make a build of the angular project.

<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.3</version>
<configuration>
<nodeVersion>v8.11.3</nodeVersion>
<npmVersion>6.3.0</npmVersion>
<workingDirectory>src/main/web/</workingDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
</execution>
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
<execution>
<id>prod</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run-script build</arguments>
</configuration>
<phase>generate-resources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
(https://dzone.com/articles/building-a-web-app-using-spring-boot-angular-6-and)

Add Spring Boot part

After we added our frontendt now comes the backend, where Intellij provides us a little help by using the integrated spring initalizr functionality. Pay attentation that you take as group the same content as in the groupId tag of your parent pom.xml. Furthermore select as packaging “War”, because we want to deploy the whole thing on a tomcat server later.

(Right-click on parent module > New > Module > Spring Initalizr)
(The web dependency will us additonally allow to create REST services)

Adjust pom.xml of the backend module

Because the backend will finally be the one who create the .war file we need to append several information to the pom.xml.

First the backend need to be aware of the frontend part by adding the following part as dependency.

<dependency>
<groupId>com.tutorial</groupId>
<artifactId>frontend</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>

For the build of the .war file the following part need to be insert inside of the project tag. Is is important to change the path (bold marked in the lower codebox) to the location where the frontend is located.

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.20.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.9.RELEASE</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<packagingExcludes>WEB-INF/lib/tomcat-*.jar</packagingExcludes>
<warName>tutorial-app</warName>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>         
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes/resources/</outputDirectory>
<resources>
<resource>
<directory>${project.parent.basedir}/frontend/src/main/web/dist/frontendApp/</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
(https://dzone.com/articles/building-a-web-app-using-spring-boot-angular-6-and)

Finally the backend module need to be announced in the pon.xml of the parent module by adding a new module tag.

<modules>
<module>frontend</module>
<module>backend</module>
</modules>

SpringBootServletInitalizer

Relating to this StackOverflow issue in the artifact with the groupId “org.springframework.boot” in the version 1.3.6 RELEASE an defective import statement had existed in the class “ServletInitializer”. Because the probleme obviously hasn’t been solved in the version 1.5.9 Release (last time checked 26.09.2018) the following change need to be made in the mentioned class.

import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

need to be replaced with

import org.springframework.boot.web.support.SpringBootServletInitializer;

Deploy project

Here are two different ways how you ca deploy the whole project. Irrespective of the following ways first of all a maven clean install of the parent project need to be made.

(View > Tool Window > Maven Projects)

Embedded Web Server Deployment

To deploy the project on the embedded web server you need to got to the maven project window and click the button “Execute a maven goal”.

Afterwards select the backend module

and excute the following command.

spring-boot:run

Tomcat

Create a new local Tomcat run configuration via Run > Edit cofnigurations. After that you have to add in the tab “Deployment” an artifact.

(Tab deployment)

Chose here the eploded backend war.

When running this configuration the during the clean install generated .war file will be deployed on the local tomcat server.

Info

Because of an bug in Tomcat version 9.0 the following lines (see bold below) must be inserted inside of the context tag in the file “context.xml” which is relative located at “Tomcat 9.0/conf/context.xml”.

`<Context><! — Default set of monitored resources. If one of these changes, the →
<! — web application will be reloaded. →
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource><! — Uncomment this to disable session persistence across Tomcat restarts →
<! —
<Manager pathname=”” />

<Resources
cachingAllowed=”true”
cacheMaxSize=”100000"
/>

</Context>