Wednesday, December 7, 2022

Maven assembly plugin

 HOWTO

Project input 

  • Java sources
  • resources files
  • 3rd party libraries for compilation only

Project output 

  • packaged JARs
  • packaged EARs
  • packaged WARs
  • config files
  • 3rd party libraries required for runtime
  • complete TAR file delivering the application

Artifact types

JAR

  • Java classes
  • descriptors

EAR

  • JARs - dependencies
  • descriptors

WAR 

  • JARs - dependencies 
  • Web code
  •  descriptors

 

 Test project

Sample assembly descriptor

<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">

    <id>package-artifacts</id>
    <!-- Final distributive format. -->
    <formats>
        <format>tar</format>
    </formats>

    <!-- Exclude current module from distributive. -->
    <includeBaseDirectory>false</includeBaseDirectory>

    <!-- Project files to include to distributive.
    ${maven.multiModuleProjectDirectory} - path to root project folder. -->
    <fileSets>
        <fileSet>
            <!-- From directory. -->
        <directory>${maven.multiModuleProjectDirectory}/add-to-distribution/docs</directory>
            <!-- Directory in distributive. -->
            <outputDirectory>docs</outputDirectory>
            <includes>
                <!-- ** - include all files of any nesting. -->
                <include>**</include>
            </includes>
        </fileSet>
    </fileSets>

    <!-- Set of modules, included in distributive. -->
    <dependencySets>
        <dependencySet>
            <includes>
                <!-- Include all modules from POM-dependencies current module. -->
                <include>*</include>
            </includes>
            <!-- Target folder for modules in distributive. -->
            <outputDirectory>modules</outputDirectory>
            <useProjectArtifact>true</useProjectArtifact>
            <useTransitiveDependencies>false</useTransitiveDependencies>
        </dependencySet>
    </dependencySets>

</assembly>

Run mvn install

INFO] -------------------------< dave:dist-assembly >-------------------------
[INFO] Building dist-assembly 1.0.0-SNAPSHOT                              [3/3]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] --- maven-assembly-plugin:2.2-beta-5:single (create-dist) @ dist-assembly ---
[INFO] Reading assembly descriptor: dist-assembly.xml
[WARNING] Cannot include project artifact: dave:dist-assembly:pom:1.0.0-SNAPSHOT; it doesn't have an associated file or directory.
[WARNING] The following patterns were never triggered in this artifact inclusion filter:
o  '*'

[INFO] Building tar : /git/java-tutorial/assembly/target/dist-assembly-1.0.0-SNAPSHOT-package-artifacts.tar
[INFO] 
[INFO] --- maven-install-plugin:2.4:install (default-install) @ dist-assembly ---
[INFO] Installing /git/java-tutorial/assembly/pom.xml to /home/dave/.m2/repository/dave/dist-assembly/1.0.0-SNAPSHOT/dist-assembly-1.0.0-SNAPSHOT.pom
[INFO] Installing /git/java-tutorial/assembly/target/dist-assembly-1.0.0-SNAPSHOT-package-artifacts.tar to /home/dave/.m2/repository/dave/dist-assembly/1.0.0-SNAPSHOT/dist-assembly-1.0.0-SNAPSHOT-package-artifacts.tar
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for parent 1.0.0-SNAPSHOT:
[INFO] 
[INFO] parent ............................................. SUCCESS [  0.208 s]
[INFO] common ............................................. SUCCESS [  1.436 s]
[INFO] dist-assembly ...................................... SUCCESS [  0.301 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.049 s
[INFO] Finished at: 2022-12-08T20:50:54+01:00
[INFO] ------------------------------------------------------------------------
[dave@dave java-tutorial]$ tar tvf /git/java-tutorial/assembly/target/dist-1.0.0-SNAPSHOT-package-artifacts.tar
-rw-r--r-- dave/dave      5181 2022-12-08 20:47 modules/common-1.0.0-SNAPSHOT.jar
drwxr-xr-x dave/dave         0 2022-12-08 20:35 docs/
-rw-r--r-- dave/dave        12 2022-12-08 20:35 docs/file-to-add.txt

Project structure

./common
./common/src
./common/src/main
./common/src/main/java
./common/src/main/java/gc
./common/src/main/java/gc/LogGC.java
./common/src/main/java/generics
./common/src/main/java/generics/AbstractValue.java
./common/src/main/java/generics/BoxInteger.java
./common/src/main/java/generics/BoxString.java
./common/src/main/java/generics/GenericsTutorial.java
./common/src/main/java/ldap
./common/src/main/java/ldap/TestLDAP.java
./common/pom.xml
./assembly
./assembly/dist-assembly.xml
./assembly/pom.xml
./add-to-distribution
./add-to-distribution/docs
./add-to-distribution/docs/file-to-add.txt
./pom.xml


Sample code

 ear

      <plugin>
        <artifactId>maven-ear-plugin</artifactId>
        <version>3.3.0</version>
        <configuration>
          <!-- configuration elements goes here -->
        </configuration>
      </plugin>

Packaged file name

${project.build.directory}/${project.build.finalName}.${project.packaging}

Copy all project dependencies to target/lib

<plugin>
   <artifactId>maven-dependency-plugin</artifactId>
   <executions>
      <execution>
         <phase>package</phase>
         <goals>
             <goal>copy-dependencies</goal>
         </goals>
             <configuration>
               <outputDirectory>${project.build.directory}/lib</outputDirectory>
             </configuration>
       </execution>
    </executions>
</plugin>

Exclude transitive dependencies 

  <dependency>
            <groupId>com.dave</groupId>
            <artifactId>dave-module</artifactId>
            <version>1.0.0</version>
            <exclusions>
                <exclusion>
                    <groupId>*</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
</dependency>

 war

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.2</version>
        <configuration>
          <webappDirectory>/sample/servlet/container/deploy/directory</webappDirectory>
        </configuration>
      </plugin>
    </plugins>
  </build>

assembly 

Exclude artifacts from dependency set

      <dependencySets>
        <dependencySet>
          ....
          <excludes>
            <exclude>commons-lang:commons-lang</exclude>
            <exclude>log4j:log4j</exclude>
          </excludes>
        </dependencySet>
        ....
      </dependencySets>

Full assembly descriptor

    <assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.1 https://maven.apache.org/xsd/assembly-2.1.1.xsd">
      <id/>
      <formats/>
      <includeBaseDirectory/>
      <baseDirectory/>
      <includeSiteDirectory/>
      <containerDescriptorHandlers>
        <containerDescriptorHandler>
          <handlerName/>
          <configuration/>
        </containerDescriptorHandler>
      </containerDescriptorHandlers>
      <moduleSets>
        <moduleSet>
          <useAllReactorProjects/>
          <includeSubModules/>
          <includes/>
          <excludes/>
          <sources>
            <useDefaultExcludes/>
            <outputDirectory/>
            <includes/>
            <excludes/>
            <fileMode/>
            <directoryMode/>
            <fileSets>
              <fileSet>
                <useDefaultExcludes/>
                <outputDirectory/>
                <includes/>
                <excludes/>
                <fileMode/>
                <directoryMode/>
                <directory/>
                <lineEnding/>
                <filtered/>
                <nonFilteredFileExtensions/>
              </fileSet>
            </fileSets>
            <includeModuleDirectory/>
            <excludeSubModuleDirectories/>
            <outputDirectoryMapping/>
          </sources>
          <binaries>
            <outputDirectory/>
            <includes/>
            <excludes/>
            <fileMode/>
            <directoryMode/>
            <attachmentClassifier/>
            <includeDependencies/>
            <dependencySets>
              <dependencySet>
                <outputDirectory/>
                <includes/>
                <excludes/>
                <fileMode/>
                <directoryMode/>
                <useStrictFiltering/>
                <outputFileNameMapping/>
                <unpack/>
                <unpackOptions>
                  <includes/>
                  <excludes/>
                  <filtered/>
                  <nonFilteredFileExtensions/>
                  <lineEnding/>
                  <useDefaultExcludes/>
                  <encoding/>
                </unpackOptions>
                <scope/>
                <useProjectArtifact/>
                <useProjectAttachments/>
                <useTransitiveDependencies/>
                <useTransitiveFiltering/>
              </dependencySet>
            </dependencySets>
            <unpack/>
            <unpackOptions>
              <includes/>
              <excludes/>
              <filtered/>
              <nonFilteredFileExtensions/>
              <lineEnding/>
              <useDefaultExcludes/>
              <encoding/>
            </unpackOptions>
            <outputFileNameMapping/>
          </binaries>
        </moduleSet>
      </moduleSets>
      <fileSets>
        <fileSet>
          <useDefaultExcludes/>
          <outputDirectory/>
          <includes/>
          <excludes/>
          <fileMode/>
          <directoryMode/>
          <directory/>
          <lineEnding/>
          <filtered/>
          <nonFilteredFileExtensions/>
        </fileSet>
      </fileSets>
      <files>
        <file>
          <source/>
          <sources/>
          <outputDirectory/>
          <destName/>
          <fileMode/>
          <lineEnding/>
          <filtered/>
        </file>
      </files>
      <dependencySets>
        <dependencySet>
          <outputDirectory/>
          <includes/>
          <excludes/>
          <fileMode/>
          <directoryMode/>
          <useStrictFiltering/>
          <outputFileNameMapping/>
          <unpack/>
          <unpackOptions>
            <includes/>
            <excludes/>
            <filtered/>
            <nonFilteredFileExtensions/>
            <lineEnding/>
            <useDefaultExcludes/>
            <encoding/>
          </unpackOptions>
          <scope/>
          <useProjectArtifact/>
          <useProjectAttachments/>
          <useTransitiveDependencies/>
          <useTransitiveFiltering/>
        </dependencySet>
      </dependencySets>
      <repositories>
        <repository>
          <outputDirectory/>
          <includes/>
          <excludes/>
          <fileMode/>
          <directoryMode/>
          <includeMetadata/>
          <groupVersionAlignments>
            <groupVersionAlignment>
              <id/>
              <version/>
              <excludes/>
            </groupVersionAlignment>
          </groupVersionAlignments>
          <scope/>
        </repository>
      </repositories>
      <componentDescriptors/>
    </assembly>

Saturday, December 3, 2022

Calling Ant from Maven using maven-antrun-plugin

 HOWTO

Sample code

            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <phase>
                            package
                        </phase>
                        <configuration>
                            <target>
                                <echoproperties />
                                <property name="compile_classpath" refid="maven.compile.classpath" />
                                <property name="runtime_classpath" refid="maven.runtime.classpath" />
                                <property name="test_classpath" refid="maven.test.classpath" />
                                <property name="plugin_classpath" refid="maven.plugin.classpath" />
                                 
                                <echo message="compile classpath: ${compile_classpath}" />
                                <echo message="runtime classpath: ${runtime_classpath}" />
                                <echo message="test classpath:    ${test_classpath}" />
                                <echo message="plugin classpath:  ${plugin_classpath}" />
                            </target>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

Ant packaged JAR installed into Maven repository

Code

<jar destfile="${project.build.directory}/ant-generated.jar" 
      basedir="${project.build.directory}/classes"
      includes="$(project.build.directory}//classes**/*.class" 
      excludes="**/Test.class"
/>

<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <groupId>dave</groupId>
                    <artifactId>ant-jar</artifactId>
                    <version>1.0</version>
                    <packaging>jar</packaging>
                    <file>target/ant-generated.jar</file>
                    <generatePom>true</generatePom>
                </configuration>
                <executions>
                    <execution>
                        <id>install-jar-lib</id>
                        <goals>
                            <goal>install-file</goal>
                        </goals>
                        <phase>package</phase>
                    </execution>
                </executions>
</plugin>

Output

INFO]       [jar] Building MANIFEST-only jar: /git/java-tutorial/common/target/ant-generated.jar
[INFO] Executed tasks
[INFO] 
[INFO] --- maven-install-plugin:2.5.1:install-file (install-jar-lib) @ tutorial ---
[INFO] pom.xml not found in ant-generated.jar
[INFO] Installing /git/java-tutorial/common/target/ant-generated.jar to /home/dave/.m2/repository/dave/ant-jar/1.0/ant-jar-1.0.jar
[INFO] Installing /tmp/mvninstall5653662900106884773.pom to /home/dave/.m2/repository/dave/ant-jar/1.0/ant-jar-1.0.pom

Special Maven properties exported to Ant


maven.multiModuleProjectDirectory=/git/java-tutorial
project.build.directory=/git/java-tutorial/common/target

Maven classpath exported into Ant

[WARNING]      [echo] compile classpath: /git/java-tutorial/common/target/classes
[WARNING]      [echo] runtime classpath: /git/java-tutorial/common/target/classes
[WARNING]      [echo] test classpath:    /git/java-tutorial/common/target/test-classes:/git/java-tutorial/common/target/classes:/home/dave/.m2/repository/junit/junit/4.11/junit-4.11.jar:/home/dave/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar
[WARNING]      [echo] plugin classpath:  /home/dave/.m2/repository/org/apache/maven/plugins/maven-antrun-plugin/3.1.0/maven-antrun-plugin-3.1.0.jar:/home/dave/.m2/repository/org/codehaus/plexus/plexus-utils/3.4.1/plexus-utils-3.4.1.jar:/home/dave/.m2/repository/org/apache/ant/ant/1.10.12/ant-1.10.12.jar:/home/dave/.m2/repository/org/apache/ant/ant-launcher/1.10.12/ant-launcher-1.10.12.jar
                      

Exporting properties from Maven to ant 

 See https://maven.apache.org/plugins/maven-antrun-plugin/usage.html 

If the Maven property you want to use is not available in an external file, you will have to redefine the property before calling ant.

      <property name="maven.project.url" value="${project.url}"/>
      <ant antfile="build.xml"/>

 Ant  properties defined in  maven-antrun-plugin call

FO] --- maven-antrun-plugin:3.1.0:run (default) @ tutorial ---
[INFO] Executing tasks
[INFO] [echoproperties] #Ant properties
[INFO] [echoproperties] #Sat Dec 03 19:41:56 CET 2022
[INFO] [echoproperties] ant.file.maven-antrun-=/git/java-tutorial/common/target/antrun/build-main.xml
[INFO] [echoproperties] sun.desktop=gnome
[INFO] [echoproperties] awt.toolkit=sun.awt.X11.XToolkit
[INFO] [echoproperties] project.build.directory=/git/java-tutorial/common/target
[INFO] [echoproperties] java.specification.version=11
[INFO] [echoproperties] failOnMissingWebXml=false
[INFO] [echoproperties] ant.project.name=maven-antrun-
[INFO] [echoproperties] sun.cpu.isalist=
[INFO] [echoproperties] sun.jnu.encoding=UTF-8
[INFO] [echoproperties] git.build.version=0.0.1-SNAPSHOT
[INFO] [echoproperties] java.class.path=/app/weblogic/oracle_common/modules/thirdparty/apache-maven_bundle/3.6.1.0.0/apache-maven-3.6.1/boot/plexus-classworlds-2.6.0.jar
[INFO] [echoproperties] project.name=tutorial
[INFO] [echoproperties] project.build.testOutputDirectory=/git/java-tutorial/common/target/test-classes
[INFO] [echoproperties] java.vm.vendor=Oracle Corporation
[INFO] [echoproperties] sun.arch.data.model=64
[INFO] [echoproperties] settings.localRepository=/home/dave/.m2/repository
[INFO] [echoproperties] project.groupId=dave
[INFO] [echoproperties] java.vendor.url=https\://openjdk.java.net/
[INFO] [echoproperties] user.timezone=Europe/Prague
[INFO] [echoproperties] project.build.outputDirectory=/git/java-tutorial/common/target/classes
[INFO] [echoproperties] maven.conf=/app/weblogic/oracle_common/modules/thirdparty/apache-maven_bundle/3.6.1.0.0/apache-maven-3.6.1/conf
[INFO] [echoproperties] java.vm.specification.version=11
[INFO] [echoproperties] os.name=Linux
[INFO] [echoproperties] ant.file.type.maven-antrun-=file
[INFO] [echoproperties] user.country=US
[INFO] [echoproperties] sun.java.launcher=SUN_STANDARD
[INFO] [echoproperties] sun.boot.library.path=/usr/java/jdk-11.0.16.1/lib
[INFO] [echoproperties] sun.java.command=org.codehaus.plexus.classworlds.launcher.Launcher clean package
[INFO] [echoproperties] jdk.debug=release
[INFO] [echoproperties] maven.home=/app/weblogic/oracle_common/modules/thirdparty/apache-maven_bundle/3.6.1.0.0/apache-maven-3.6.1
[INFO] [echoproperties] sun.cpu.endian=little
[INFO] [echoproperties] maven.compiler.source=11
[INFO] [echoproperties] user.home=/home/dave
[INFO] [echoproperties] project.build.testSourceDirectory=/git/java-tutorial/common/src/test/java
[INFO] [echoproperties] user.language=en
[INFO] [echoproperties] org.hamcrest\:hamcrest-core\:jar=/home/dave/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar
[INFO] [echoproperties] java.specification.vendor=Oracle Corporation
[INFO] [echoproperties] project.artifactId=tutorial
[INFO] [echoproperties] project.version=0.0.1-SNAPSHOT
[INFO] [echoproperties] java.version.date=2022-08-18
[INFO] [echoproperties] java.home=/usr/java/jdk-11.0.16.1
[INFO] [echoproperties] basedir=/git/java-tutorial/common
[INFO] [echoproperties] file.separator=/
[INFO] [echoproperties] project.packaging=jar
[INFO] [echoproperties] java.vm.compressedOopsMode=Zero based
[INFO] [echoproperties] line.separator=\n
[INFO] [echoproperties] ant.java.version=11
[INFO] [echoproperties] java.specification.name=Java Platform API Specification
[INFO] [echoproperties] java.vm.specification.vendor=Oracle Corporation
[INFO] [echoproperties] java.awt.graphicsenv=sun.awt.X11GraphicsEnvironment
[INFO] [echoproperties] git.commit.id.full=ff3ab46b0d66dfa9c433058be438f2cb0c2ea3b1
[INFO] [echoproperties] git.build.time=2022-12-03T19\:41\:55+0100
[INFO] [echoproperties] sun.management.compiler=HotSpot 64-Bit Tiered Compilers
[INFO] [echoproperties] java.runtime.version=11.0.16.1+1-LTS-1
[INFO] [echoproperties] user.name=dave
[INFO] [echoproperties] ant.file=/git/java-tutorial/common/pom.xml
[INFO] [echoproperties] path.separator=\:
[INFO] [echoproperties] securerandom.source=file\:/dev/./urandom
[INFO] [echoproperties] os.version=6.0.10-200.fc36.x86_64
[INFO] [echoproperties] java.runtime.name=Java(TM) SE Runtime Environment
[INFO] [echoproperties] file.encoding=UTF-8
[INFO] [echoproperties] guice.disable.misplaced.annotation.check=true
[INFO] [echoproperties] java.vm.name=Java HotSpot(TM) 64-Bit Server VM
[INFO] [echoproperties] java.vendor.version=18.9
[INFO] [echoproperties] localRepository=\      id\: local\n      url\: file\:///home/dave/.m2/repository/\n   layout\: default\nsnapshots\: [enabled \=> true, update \=> always]\n releases\: [enabled \=> true, update \=> always]\n
[INFO] [echoproperties] ant.core.lib=/home/dave/.m2/repository/org/apache/ant/ant/1.10.12/ant-1.10.12.jar
[INFO] [echoproperties] java.vendor.url.bug=https\://bugreport.java.com/bugreport/
[INFO] [echoproperties] java.io.tmpdir=/tmp
[INFO] [echoproperties] java.version=11.0.16.1
[INFO] [echoproperties] user.dir=/git/java-tutorial
[INFO] [echoproperties] os.arch=amd64
[INFO] [echoproperties] maven.multiModuleProjectDirectory=/git/java-tutorial
[INFO] [echoproperties] git.commit.id.abbrev=ff3ab46
[INFO] [echoproperties] java.vm.specification.name=Java Virtual Machine Specification
[INFO] [echoproperties] java.awt.printerjob=sun.print.PSPrinterJob
[INFO] [echoproperties] sun.os.patch.level=unknown
[INFO] [echoproperties] ant.version=Apache Ant(TM) version 1.10.12 compiled on October 13 2021
[INFO] [echoproperties] maven.compiler.target=11
[INFO] [echoproperties] java.library.path=/usr/java/packages/lib\:/usr/lib64\:/lib64\:/lib\:/usr/lib
[INFO] [echoproperties] project.build.sourceDirectory=/git/java-tutorial/common/src/main/java
[INFO] [echoproperties] java.vm.info=mixed mode
[INFO] [echoproperties] java.vendor=Oracle Corporation
[INFO] [echoproperties] java.vm.version=11.0.16.1+1-LTS-1
[INFO] [echoproperties] classworlds.conf=/app/weblogic/oracle_common/modules/thirdparty/apache-maven_bundle/3.6.1.0.0/apache-maven-3.6.1/bin/m2.conf
[INFO] [echoproperties] sun.io.unicode.encoding=UnicodeLittle
[INFO] [echoproperties] library.jansi.path=/app/weblogic/oracle_common/modules/thirdparty/apache-maven_bundle/3.6.1.0.0/apache-maven-3.6.1/lib/jansi-native
[INFO] [echoproperties] maven.project.dependencies.versions=4.11\:1.3\:
[INFO] [echoproperties] java.class.version=55.0
[INFO] [echoproperties] junit\:junit\:jar=/home/dave/.m2/repository/junit/junit/4.11/junit-4.11.jar
[INFO] [echoproperties] ant.project.default-target=main
[WARNING]      [echo] compile classpath: /git/java-tutorial/common/target/classes
[WARNING]      [echo] runtime classpath: /git/java-tutorial/common/target/classes
[WARNING]      [echo] test classpath:    /git/java-tutorial/common/target/test-classes:/git/java-tutorial/common/target/classes:/home/dave/.m2/repository/junit/junit/4.11/junit-4.11.jar:/home/dave/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar
[WARNING]      [echo] plugin classpath:  /home/dave/.m2/repository/org/apache/maven/plugins/maven-antrun-plugin/3.1.0/maven-antrun-plugin-3.1.0.jar:/home/dave/.m2/repository/org/codehaus/plexus/plexus-utils/3.4.1/plexus-utils-3.4.1.jar:/home/dave/.m2/repository/org/apache/ant/ant/1.10.12/ant-1.10.12.jar:/home/dave/.m2/repository/org/apache/ant/ant-launcher/1.10.12/ant-launcher-1.10.12.jar