lab 01

Using the Maven build tool and creating self-executing packages

Maven - creating a project

Create a new Java project using the Maven Archetype.

Use Archetype io.github.jez04-cs:java21-quickstart

The actual project will not be org.example or untitled, but something meaningful like cz.vsb. or any domain close to you and a reasonable name.

Idea - needs lombok installed:

new project -> Maven Archetype -> Catalog: Maven Central -> Archatype: type jez04 will find 3 of my archetypes select the above -> Advanced Settings -> fill in reasonable values -> Create

Eclipse - needs lombok installed:

File -> New -> Maven Project -> Next -> Filter: jez04 -> clear the above from the ones found -> Next -> Fill in sensible -> Finish

Press < Enter > in the Console tab

Command line - must have Maven downloaded/installed:

mvn archetype:generate -DarchetypeGroupId=io.github.jez04-cs -DarchetypeArtifactId=java21-quickstart -DgroupId=en.jezek -DartifactId=jez04-test -Dversion=1.0-SNAPSHOT -Dpackage=en.jezek.testgen

Add dependencies

Add dependencies for Unit tests in Kelvin

        <dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.10.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>3.0</version>
<scope>test</scope>
</dependency>

Implements

Ascii Art text is created from the specified text. Follow the steps:

  • Read the text using the command line parameter as -text mujTextProConversion
  • Load the text from the console if the application will run with the parameter -cli

The text is first loaded as a command line parameter. If not specified it is loaded from the console.

To convert, use the io.github.jez04-cs.lab01text2asciiart.Text2AsciiArt class in the io.github.jez04-cs:lab01-text2asciiart:1.0.3 library (use the latest version). The library is in the https://artifactory.cs.vsb.cz/#browse/browse:education-releases repository as a "maven dependency" (see lectures) So you need to add your own (school) repository.

Compilation, packaging, cleaning

  • mvn compile
  • mvn package
  • mvn clean

Creating a JAR package for distribution and execution without an IDE

"Fat" jar - jar with wrapped dependencies (problem with modules and more)

            <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.6.0</version>

<configuration>
<!--Set behavior of plugin, which archives should be created see
https://maven.apache.org/plugins/maven-assembly-plugin/descriptor-refs.html-->
<descriptorRefs>
<!--Create FAT jar-->
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<!--Automatically create and add file MANIFEST.MF into jar and set specified properties-->
<manifest>
<mainClass>cz.vsb.fei.App --must be changed</mainClass>
</manifest>
</archive>
</configuration>

<executions>
<!-- Setup that goal single should be automatically executed during phase package-->
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>

Starting the application

  • via maven: mvn exec:java -Dexec.mainClass=name_of_main_class
  • without maven: java -cp path_to_jar name_of_main_class
  • fat jar: java -jar your_fat_jar.jar

"JAR with LIBS" - jar and its libraries

Warning, the values in manifestEntries and manifest are sensitive to extra spaces and newlines, which can be created for example by automatic formatting of pom.xml.

            <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.8.1</version>
<executions>
<!-- Setup that goal copy-dependencies should be automatically executed during phase package-->
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!--Specify where should be dependencies (libraries) copied-->
<outputDirectory>${project.build.directory}/libs</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<!--Automatically create and add file MANIFEST.MF into jar and set specified additional properties-->
<manifestEntries>
<Name>cz/vsb/fei/App --must be changed</Name>
<Implementation-Build-Date>${maven.build.timestamp}</Implementation-Build-Date>
<Implementation-Title>${project.groupId}.${project.artifactId}</Implementation-Title>
<Implementation-Vendor>VŠB FEI Departmet of Computer Science</Implementation-Vendor>
<Implementation-Version>${project.version}</Implementation-Version>
</manifestEntries>
<!--Automatically create and add file MANIFEST.MF into jar and set specified properties-->
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>cz.vsb.fei.App --must be changed</mainClass>
</manifest>
</archive>
</configuration>
</plugin>

Starting the application

Without maven: java -jar name_of_jar_file

Using JLINK (creates separate slimmed down JDK/JRE)

            <plugin>
<!--Plugin create customized version of JDK together with your application which can be
distributed to any computer with same platform where you build this Jlink-->
<artifactId>maven-jlink-plugin</artifactId>
<version>3.2.0</version>
<extensions>true</extensions>
<executions>
<!-- Setup that goal jlink should be automatically executed during phase package-->
<execution>
<id>create-jlink-image</id>
<phase>package</phase>
<goals>
<goal>jlink</goal>
</goals>
</execution>
</executions>
<configuration>
<!--Set classifier name to change suffix of generated file, otherwise module finish with error-->
<classifier>jlink</classifier>
</configuration>
</plugin>

Starting the application

Using JLINK image - no need JDK:

target/image/bin/java -m cz.vsb.fei.java2.jez04lab01/cz.vsb.fei.java2.jez04lab01.App

General:

target/image/bin/java -m your.module.name/your.module.main.classs.name

M2E plugin error in Eclipse

The current version of eclipse has a bug in the plugin that integrates the entire Maven lifecycle into Eclipse. It has a problem with the maven-dependency-plugin, which is not important for Eclipse. The bug can be ignored, or the Maven configuration can be used to disable the plugin in Eclipse. Just add this to the TAG buid:

<pluginManagement>
<plugins>
<!-- Ignore/Execute plugin execution in Eclipse (error of m2e eclipse plugin) -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<!-- copy-dependency plugin -->
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<versionRange>[1.0.0,)</versionRange>
<goals>
<goal>copy-dependencies</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>