Thursday, 8 October 2020

Getting to grips with Maven - in five minutes ...

As part of my investigation into SonarQube, as per: -

Tinkering with SonarQube for code-scanning shell scripts ... 

I wanted to validate SQ's ability to scan Java projects.

SQ "assumes" that you're either using Maven or Gradle: -


so I thought I'd play with Maven, having used it for other Java work recently.

Thankfully, the Apache Maven project has a really useful tutorial on their site: -

Maven in 5 Minutes

which I followed, both on a Linux virtual server and on my Mac.

Here's a whiz-through the tutorial on my Mac ( with a bit of editorialising on my part ) : -

Validate Maven version

mvn --version

Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)

Maven home: /usr/local/Cellar/maven/3.6.3_1/libexec

Java version: 1.8.0_251, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre

Default locale: en_GB, platform encoding: UTF-8

OS name: "mac os x", version: "10.15.7", arch: "x86_64", family: "mac"

Creating a Project

mvn archetype:generate -DgroupId=com.dave.app -DartifactId=daves-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false

[INFO] Scanning for projects...
....
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: maven-archetype-quickstart:1.4
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.dave.app
[INFO] Parameter: artifactId, Value: daves-app
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.dave.app
[INFO] Parameter: packageInPathFormat, Value: com/dave/app
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.dave.app
[INFO] Parameter: groupId, Value: com.dave.app
[INFO] Parameter: artifactId, Value: daves-app
[INFO] Project created from Archetype in dir: /Users/hayd/daves-app
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  56.777 s
[INFO] Finished at: 2020-10-08T07:53:00+01:00
[INFO] ------------------------------------------------------------------------


This created a new project folder, with subdirectories: -

tree daves-app/

daves-app/
├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── com
    │           └── dave
    │               └── app
    │                   └── App.java
    └── test
        └── java
            └── com
                └── dave
                    └── app
                        └── AppTest.java

11 directories, 3 files

including pom.xml : -

cat daves-app/pom.xml

<?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.dave.app</groupId>
  <artifactId>daves-app</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>daves-app</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
...

and, of course, the Java app: -

cat ./src/main/java/com/dave/app/App.java

package com.dave.app;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}

mvn package

[INFO] Scanning for projects...
[INFO] 
[INFO] -----------------------< com.dave.app:daves-app >-----------------------
[INFO] Building daves-app 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
...

[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.dave.app.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.023 s - in com.dave.app.AppTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] 
[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ daves-app ---
...

[INFO] Building jar: /Users/hayd/daves-app/target/daves-app-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  27.681 s
[INFO] Finished at: 2020-10-08T08:00:09+01:00
[INFO] ------------------------------------------------------------------------

mvn validate

[INFO] Scanning for projects...
[INFO] 
[INFO] -----------------------< com.dave.app:daves-app >-----------------------
[INFO] Building daves-app 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.079 s
[INFO] Finished at: 2020-10-08T08:16:49+01:00
[INFO] ------------------------------------------------------------------------

find . -name `ls -R | grep \.jar`

./target/daves-app-1.0-SNAPSHOT.jar

ls -al target/daves-app-1.0-SNAPSHOT.jar 

-rw-r--r--  1 hayd  staff  2687  8 Oct 08:00 target/daves-app-1.0-SNAPSHOT.jar

tree

.
├── pom.xml
├── src
│   ├── main
│   │   └── java
│   │       └── com
│   │           └── dave
│   │               └── app
│   │                   └── App.java
│   └── test
│       └── java
│           └── com
│               └── dave
│                   └── app
│                       └── AppTest.java
└── target
    ├── classes
    │   └── com
    │       └── dave
    │           └── app
    │               └── App.class
    ├── daves-app-1.0-SNAPSHOT.jar
    ├── generated-sources
    │   └── annotations
    ├── generated-test-sources
    │   └── test-annotations
    ├── maven-archiver
    │   └── pom.properties
    ├── maven-status
    │   └── maven-compiler-plugin
    │       ├── compile
    │       │   └── default-compile
    │       │       ├── createdFiles.lst
    │       │       └── inputFiles.lst
    │       └── testCompile
    │           └── default-testCompile
    │               ├── createdFiles.lst
    │               └── inputFiles.lst
    ├── surefire-reports
    │   ├── TEST-com.dave.app.AppTest.xml
    │   └── com.dave.app.AppTest.txt
    └── test-classes
        └── com
            └── dave
                └── app
                    └── AppTest.class

32 directories, 13 files


Run the App

java -cp target/daves-app-1.0-SNAPSHOT.jar com.dave.app.App

Hello World!

Change the App

vi ./src/main/java/com/dave/app/App.java

package com.dave.app;

/**
 * Hello world!
 *
 */
public class App
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!, you rule :-)" );
    }
}

Rebuild the App

mvn package

[INFO] Scanning for projects...
[INFO] 
[INFO] -----------------------< com.dave.app:daves-app >-----------------------
[INFO] Building daves-app 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ daves-app ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/hayd/daves-app/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ daves-app ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/hayd/daves-app/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:3.0.2:testResources (default-testResources) @ daves-app ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/hayd/daves-app/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ daves-app ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ daves-app ---
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.dave.app.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.02 s - in com.dave.app.AppTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] 
[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ daves-app ---
[INFO] Building jar: /Users/hayd/daves-app/target/daves-app-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.203 s
[INFO] Finished at: 2020-10-08T09:00:13+01:00
[INFO] ------------------------------------------------------------------------

Run the App

java -cp target/daves-app-1.0-SNAPSHOT.jar com.dave.app.App

Hello World!, you rule :-)

Thanks for Apache Maven for their tutorial: -
Right, back to SonarQube ......


No comments:

Note to self - use kubectl to query images in a pod or deployment

In both cases, we use JSON ... For a deployment, we can do this: - kubectl get deployment foobar --namespace snafu --output jsonpath="{...