2. Development Tools 2(62)
Content
●
Project management and build, Maven
●
Testing, Spring MVC Test
●
Continuous integration and delivery (CI/CD),
Docker and GitHub Actions
●
Static Analyzer, PMD and SpotBugs
●
Dependency analysis, Apache Maven
Dependency Plugin
●
Code coverage, JaCoCo
3. Development Tools 3(62)
Project Management and Build With
Maven
Maven Home page:
http://maven.apache.org/
Tutorial, user guide and reference manual:
http://maven.apache.org/guides/index.html
4. Development Tools 4(62)
Maven, Content
●
Why do we need a build tool? What is a
project management tool?
●
Maven architecture
●
Pom file
●
Using Maven Command Line Interface
5. Development Tools 5(62)
Why do we need a build tool?
●
All actions (compile, deploy, run, create
documentation, etc.) must be well-defined and
reproducible.
– We need to store commands, switches, command
line arguments, environment variables (like
classpath), etc.
●
All IDEs use a build tool.
– Configured via IDE dialogs instead of editing the
build tool's script text files.
●
Many IDEs use Ant for building.
6. Development Tools 6(62)
Maven vs Ant
●
An ant file is like a program, you specify what
to do, when to do it and where (in which
directory) the used files are found.
●
With maven you only specify what to do, e.g.,
compile, not how to do it.
– Many common tasks, like compiling, are done by
default, you do not even need to specify them.
●
As a result, a maven script becomes shorter
and easier to understand than an ant script.
7. Development Tools 7(62)
Maven vs Ant (Cont'd)
●
Ant forces you to manage all files yourself.
– Manually download all third-party jars your code
depends on and place them in correct directory.
– Often very cumbersome and time-consuming.
●
Maven defines your project's directory structure
and manages all files in the project.
– Just specify the dependencies and maven
downloads needed jars and uses them as required.
8. Development Tools 8(62)
What is a project management tool?
●
Maven not only builds the project.
●
Also defines project directory structure, which
tasks to perform and in what order.
9. Development Tools 9(62)
Maven Philosophy
●
Maven defines project directory structure.
– Always the same, no configuration needed.
●
Maven defines what to do and in which order.
– Always the same, no configuration needed.
●
User only defines a unique project name,
package format (jar, war...) and dependencies
(third-party products used).
– Much more configuration is of course possible.
10. Development Tools 10(62)
Lifecycles, Phases and Goals
●
Maven projects consist of lifecycles, which are
divided in phases, which are divided in goals.
●
There are three lifecycles: default, clean and
site.
– Default lifecycle creates the application.
– Clean lifecycle removes all files generated by
maven.
– Site lifecycle generates a web site with project
documentation.
11. Development Tools 11(62)
Major Phases in Default Lifecycle
●
process-resources, Copy resources directory into
destination directory.
●
compile, Compile the source code.
●
process-test-resources, Copy resources directory
into the test destination directory.
●
test-compile, Compile the test source code.
●
test, Run tests using a suitable unit testing
framework.
●
package, Package compiled code in JAR (or other).
●
install, Install the package into the local repository.
●
deploy, Copy the package to the remote repository.
12. Development Tools 12(62)
Clean and Site lifecycle
●
These lifecycles have only one important
phase each.
– Clean lifecycle has clean phase.
– Site lifecycle has site phase.
13. Development Tools 13(62)
Execution
●
To run maven, you specify a phase.
●
Phases in the lifecycle of the specified phase
are executed in order.
●
The lifecycle starts from the beginning and
stops after the specified phase.
14. Development Tools 14(62)
What Happens in Each Phase?
●
Each phase executes a set of goals.
●
The packaging type decides which goals
belong to which phase.
– Additional goals can be added manually.
●
A goal is actually a piece of Java code, which
is packaged in a plugin.
– One plugin can define many goals
15. Development Tools 15(62)
Typical Goals
The jar and war packaging types use (at least) the
following goals.
Phase plugin:goal
process-resources resources:resources
compile compiler:compile
process-test-resources resources:testResources
test-compile compiler:testCompile
test surefire:test
package jar:jar or war:war
install install:install
deploy deploy:deploy
16. Development Tools 16(62)
Packages are Stored in Repositories
●
Maven stores all packaged products (mainly
jars) in repositories.
– Enables Maven to handle all dependencies since
needed jars can be downloaded from repositories
where they are stored.
– Promotes code reuse since local repositories can
be used to share jars between projects.
●
There is a default central repository and a local
repository will be created.
– Other repositories must be specified as a
dependency.
17. Development Tools 17(62)
Project Object Model
●
A Maven project is described in a Project
Object Model file, pom.xml.
●
The pom describes, at least, a unique name
for the product and which dependencies it has
(that is, which third-party products it uses).
●
All POMs inherit a parent POM. If the parent is
not specified it inherits the default POM.
– The used POM, including inherited data is shown
with the command mvn help:effective-pom
18. Development Tools 18(62)
The Sample Application POM
●
groupId,
artifactId
and version
together
defines a
unique name
for the created
archive.
●
packaging
decides the
archive format
for the product.
<groupId>se.kth.id1212</groupId>
<artifactId>appserv-spring</artifactId>
<version>2.0</version>
<packaging>jar</packaging>
19. Development Tools 19(62)
The Sample Application POM (Cont'd)
●
Parent defines a POM that is inherited by this POM;
information from the parent POM is merged into this POM.
●
The spring-boot-starter-parent POM defines a basic
setup for a spring boot project, but does not include any other
spring frameworks.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>LATEST</version>
</parent>
20. Development Tools 20(62)
The Sample Application POM (Cont'd)
●
properties are constants that can be used in other
places in the POM.
<properties>
<docker.image.prefix>se.kth.id1212</docker.image.prefix>
...
</properties>
21. Development Tools 21(62)
The Sample Application POM (Cont'd)
●
A dependency defines a package that is required by the application. That
package will be downloaded by maven.
●
scope decides when the downloaded package shall be available.
– Default is compile, which means it is always available.
– test means it will not be available at runtime, except when tests are
executed.
●
The spring-boot-starter artifacts are not specific packages, but instead
define a set of packages needed for a prticular task.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
</dependencies>
23. Development Tools 23(62)
In-Container Testing With
Spring MVC Test
Documentation:
http://docs.spring.io/spring/docs/current/spring-framework-
reference/testing.html#spring-mvc-test-framework
25. Development Tools 25(62)
In-Container Tests
●
Runs inside a container, which is identical to the
container of the live application.
●
All resources, like persistence managers and
database connections, used by the application
are available to the test.
●
Everything, for example dependency injection,
works the same way in the test as in the live
application.
●
Components are tested in real environment.
26. Development Tools 26(62)
The Alternative, Mocking
●
No container is available.
●
All resources, for example injected objects and
database connections, must be substituted by
fake objects (mocking).
●
Components are tested in artificial
environment.
27. Development Tools 27(62)
How Spring MVC Test Framework
Works
●
Spring MVC Test Framework performs in-container tests only as far as
Spring is concerned.
– The Spring container is authentic, but the servlet container is mocked and there
is no server running.
●
In brief, the steps performed when executing a test are as follows.
1) A complete spring container is created, and injected into the test class as a
WebApplicationContext object. This container contains the application that is
being tested.
2) A MockMvc object is created, with a reference to the spring container created in
step 1.
3) The MockMvc object is used to “send” fake http requests to the spring dispatcher
servlet in the spring container. These requests are in reality method calls to the
dispatcher servlet.
4) The http response generated by the application in the spring conatiner is
evaluated.
28. Development Tools 28(62)
Spring MVC Test Installation
●
No installation is required except to specify
dependencies in the POM.
●
The archives needed to use the Spring MVC Test
framework are the dependencies with test scope
in the sample application's POM.
29. Development Tools 29(62)
Spring MVC Test Configuration
●
Quite a lot of configuration is needed. This is done
by adding annotations to test classes.
●
The annotations are often the same in different
classes, and might be considered boilerplate code
that is simply copied to all new test classes.
●
However, not understanding the configuration can
introduce strange bugs that are difficult to solve.
30. Development Tools 30(62)
A Spring MVC Test Class
●
Makes the test class callable by Junit 5
●
Instructs the test framework to load a
WebApplicationContext, which is a spring
container for a web application.
@SpringJUnitWebConfig(initializers =
ConfigFileApplicationContextInitializer.class)
31. Development Tools 31(62)
A Spring MVC Test Class, Cont'd
●
Starts Spring Boot autoconfiguration, which is
based mainly on what is found on the classpath
and on which beans are defined.
@EnableAutoConfiguration
32. Development Tools 32(62)
A Spring MVC Test Class, Cont'd
●
Makes Spring scan packages for @Components,
which are bean definitions.
@ComponentScan(basePackages = {"se.kth.id1212.appserv.bank"})
33. Development Tools 33(62)
A Spring MVC Test Class, Cont'd
●
Lists classes that shall be notified about test events, like
starting and completing tests. The following classes are
notified.
– DependencyInjectionTestExecutionListener performs
dependency injection in test class instances.
– The test class itself, AcctControllerTest in the example, must
be notified because it creates the database and connection
pool before testing.
– TransactionalTestExecutionListener creates the transaction
manager before testing.
@TestExecutionListeners(listeners = {
DependencyInjectionTestExecutionListener.class,
AcctControllerTest.class,
TransactionalTestExecutionListener.class
})
34. Development Tools 34(62)
A Spring MVC Test Class, Cont'd
●
Tells maven (or rather, the surefire maven plugin,
which executes tests) to execute test methods
sequentially, instead of in parallell.
@NotThreadSafe
35. Development Tools 35(62)
A Spring MVC Test Class, Cont'd
●
Creates a MockMVC instance, that is used to send
fake http requests to the application under test.
MockMvcBuilders.webAppContextSetup(webappContext).build();
36. Development Tools 36(62)
A Spring MVC Test Class, Cont'd
●
Sends a fake http post request to the specified url,
using the specified (fake) session and the
specified http parameters.
mockMvc.perform(post(Url).session((MockHttpSession)session).params(params))
37. Development Tools 37(62)
Continuous Integration And Delivery
(CI/CD) With
Docker And GitHub Actions
GitHub Actions Documentation:
https://docs.github.com/en/free-pro-team@latest/actions
Docker Documentation:
https://docs.docker.com/
38. Development Tools 38(62)
Continuous Integration And Delivery
(CI/CD), Content
●
What is Continuous Integration and Delivery?
●
An Introduction to the GitHub Continuous
Integration Server.
●
What is Containerization?
●
An Introduction to Docker.
39. Development Tools 39(62)
Continuous Integration (CI)
●
A software development practice where
developers frequently integrate code into a
shared repository.
●
Each check-in is verified by an automated build,
in order to detect problems as quickly as
possible.
●
The automated build includes all code evaluation
and management, for example tests, dependency
reports, static analysers and repository updates.
40. Development Tools 40(62)
A CI Server
●
A continuous integration (CI) server manages all parts
included in a build.
●
Using a CI server all team members perform exactly
the same tasks on each submit.
●
While developing, team members perform all tests
locally, in the IDE.
●
Newly developed code is automatically submitted to
the CI server, for example when a pull request is
created. The CI server then runs all checks on the
entire codebase and publishes the result.
41. Development Tools 41(62)
Continuous Delivery (CD)
●
Continous delivery means that, in addition to the
automated testing of continuous integration, also the
release process is automated.
●
When the application is ready for release, just 'one
click' is required to deploy it live.
●
The 'D' in CD can also mean deployment. Continous
deployment means that deployment is completely
automated, no human intervention at all is required.
Instead, code is deployed as soon as all tests pass.
42. Development Tools 42(62)
Continuous Integration With GitHub
●
The sample application uses GitHub actions. There is no
set up, all that is required to use GitHub actions is to
specify the what shall be done in a yaml file in the
directory .github/workflows in the repository root.
– See the tutorial at https://docs.github.com/en/free-pro-
team@latest/actions/quickstart for more information on
getting started.
●
A build is started whenever code is pushed, or a pull
request is made, to the repository.
●
The specified maven lifecycle will be executed up to the
specified phase, just as in any maven execution.
43. Development Tools 43(62)
GitHub Actions Configuration
●
GitHub actions are configured with yaml files in the directory .github/workflows.
●
Some highlights from the ci.yml of the sample application:
– jobs: mvn-verify A job specifies what shall be done. It consists of a list of steps:, each
of which specifies one command to execute. This workflow has one job, called ‘mvn-verify’.
– container: Tells to run the build in the specified docker container.
– env: Specifies environment variables to use in each build. It’s a best practice to place
configuration in environment variables, since that makes the configuration independent of
the application.
– services: Tells that the specified servcies, postgres in this case, shall be available to the
job.
– uses: Specifies a predefined action to be executed. Many actions are available in the
GitHub marketplace.
– run: is a command that shall be executed. This job is executed in the openjdk:14-jdk-slim
docker container, which uses the Alpine Linux operating system. Therefore commands in
that operating system are available.
44. Development Tools 44(62)
What is Containerization?
●
Application containerization is a way to execute
multiple applications on the same computer
– Apps are completely isolated from each other.
– It is not required to launch an entire virtual machine
for each app.
●
Also, an application can be packaged in one
single file, together with its complete runtime
environment.
– This includes OS, server, and environment variables.
45. Development Tools 45(62)
Docker
●
Docker is the dominating container technology.
●
An application is packaged in an image, which
is an executable, containing everything needed
to run an application: code, server, libraries,
environment variables, etc.
●
A container is a running image, with state.
– Each container is a process, it is isolated from other
containers but shares the OS kernel of the host
machine with all other containers.
46. Development Tools 46(62)
Create The Docker Image
●
The sample application contains the dockerfile
maven plugin, which creates the docker image
during the maven build.
●
The docker image is created during the install
phase.
47. Development Tools 47(62)
Specify What The Docker Container
Shall Do When Started
●
When a docker container is started, it executes commands in a
file called Dockerfile.
●
Some highlights from the Dockerfile of the sample application:
– FROM openjdk:14-jdk-slim defines that the base image is Debian with
openjdk 14. A base image is specified in order to not have to
specify all content explicitly.
– ARG JAR_FILE Says that docker takes one command line argument,
which is called JAR_FILE. This value is used when building the
image, not when starting a conatiner.
– COPY ${JAR_FILE} app.jar Copies the file whose name was specified
in the JAR_FILE parameter to app.jar
– CMD executes the specified command.
– EXPOSE 8080 tells that the container listens for TCP connections on
port 8080.
48. Development Tools 48(62)
Start The Docker Container
●
docker images lists all local docker images.
●
docker run -p 8080:8080
se.kth.id1212/appserv-spring:2.0 starts the
docker image se.kth.id1212/appserv-
spring:2.0 and exports the image's port 8080
on port 8080 on the host.
49. Development Tools 49(62)
Static Analyzing With PMD and
SpotBugs
PMD Home Page:
https://pmd.github.io/
SpotBugs Home Page:
https://spotbugs.github.io/
51. Development Tools 51(62)
Why Do Static Analysis?
●
Static analysis means the code is analyzed
without executing the program.
●
A static analyzer checks for coding mistakes. It
can be for example bugs, unneccessary code,
badly formatted code or security vulnerabilities.
●
Like the compiler, such a tool helps find coding
errors.
●
Many of the flaws found by a static analyzer will
not be found by executing the program.
52. Development Tools 52(62)
Static Analyzing With PMD
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.10.0</version>
<configuration>
<verbose>true</verbose>
<failOnViolation>true</failOnViolation>
<minimumTokens>50</minimumTokens>
<excludeFromFailureFile>
excludeFromPmdCheck.properties
</excludeFromFailureFile>
<outputDirectory>${pmd.output.dir}</outputDirectory>
<targetDirectory>${pmd.target.dir}</targetDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
<goal>cpd-check</goal>
</goals>
<phase>validate</phase>
</execution>
</executions>
</plugin>
●
PMD is declared as
a plugin in the
POM, and executed
by maven.
●
PMD checks many
rules, and is quite
hard. It might be
necessary to
exclude rules,
which is done by
listing them in the
file indicated by
excludeFromFailureFile
●
<goal>check</goal>
runs PMD rules
●
<goal>cpd-check</
goal> checks for
duplicated code.
53. Development Tools 53(62)
Static Analyzing With PMD, Cont'd
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.10.0</version>
<configuration>
<verbose>true</verbose>
<failOnViolation>true</failOnViolation>
<minimumTokens>50</minimumTokens>
<excludeFromFailureFile>
excludeFromPmdCheck.properties
</excludeFromFailureFile>
<outputDirectory>${pmd.output.dir}</outputDirectory>
<targetDirectory>${pmd.target.dir}</targetDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
<goal>cpd-check</goal>
</goals>
<phase>validate</phase>
</execution>
</executions>
</plugin>
●
The reports are
printed to standard
out, and written to
files in
outputDirectory
54. Development Tools 54(62)
Static Analyzing With SpotBugs
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>3.1.9</version>
<configuration>
<effort>Max</effort>
<threshold>medium</threshold>
<xmlOutput>true</xmlOutput>
<failOnError>true</failOnError>
<xmlOutputDirectory>${spotbugs.output.dir}</xmlOutputDirectory>
<plugins>
<plugin>
<groupId>com.h3xstream.findsecbugs</groupId>
<artifactId>findsecbugs-plugin</artifactId>
<version>LATEST</version>
</plugin>
</plugins>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
●
Also SpotBugs is
declared as a
plugin in the POM,
and executed by
maven.
●
The findsecbugs
plugin checks for
security
vulnerabilities.
●
The reports are
printed to standard
out, and written to
files in
xmlOutputDirectory
55. Development Tools 55(62)
Static Analyzing With SpotBugs
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>3.1.9</version>
<configuration>
<effort>Max</effort>
<threshold>medium</threshold>
<xmlOutput>true</xmlOutput>
<failOnError>true</failOnError>
<xmlOutputDirectory>${spotbugs.output.dir}</xmlOutputDirectory>
<plugins>
<plugin>
<groupId>com.h3xstream.findsecbugs</groupId>
<artifactId>findsecbugs-plugin</artifactId>
<version>LATEST</version>
</plugin>
</plugins>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
●
Effort defines trade-off
between computation
resources and
performed checks. Max
means to perform all
checks.
●
<threshold>medium
</threshold> means
that low confidence
issues are supressed.
Exactly what this means
is unfortunately quite
unclear.
56. Development Tools 56(62)
Dependency analysis With Apache
Maven Dependency Plugin
Home Page:
https://maven.apache.org/plugins/maven-dependency-
plugin/
57. Development Tools 57(62)
Dependency analysis With Apache
Maven Dependency Plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<sort>true</sort>
</configuration>
<executions>
<execution>
<goals>
<goal>resolve</goal>
<goal>tree</goal>
<goal>list-repositories</goal>
<goal>analyze-only</goal>
<goal>analyze-duplicate</goal>
<goal>display-ancestors</goal>
</goals>
<phase>validate</phase>
</execution>
</executions>
</plugin>
●
This maven plugin analyzes
the project's dependencies.
●
resolve displays the version
of all dependencies.
●
tree displays dependecy
relations as a tree.
●
list-repositories lists the
repositories used.
●
analyze-only determines
which dependencies are:
used and declared; used and
undeclared; unused and
declared.
●
analyze-duplicate checks
if there are duplicate
declared dependencies.
●
display-ancestors displays
all ancestor POMs
58. Development Tools 58(62)
Code Coverage With JaCoCo
JaCoCo Home Page:
http://www.eclemma.org/jacoco/
Documentation:
http://www.eclemma.org/jacoco/trunk/doc/
60. Development Tools 60(62)
What is a Code Coverage Tool?
●
Records which parts of the program have been
executed during a test and generates a report of
the coverage.
●
Visualizes how complete the tests are.
●
It is normally not meaningful to strive for 100%
coverage, for example getters and setters may be
omitted from the test.
●
We shall, however, make sure all important parts
of the code are tested.
62. Development Tools 62(62)
JaCoCo Basics (Cont'd)
Open the file <project root>/target/site/jacoco/index.html in a
browser to see reports of test coverage.