0

Our project have dependency on several other company project jars and third party jars. During build, we are copying them to two separate folders ${project.build.directory}/third-party-jars/ and ${project.build.directory}/mycompany-jars/ using maven-dependency-plugin:copy-dependency goal as follows:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>build-thirdparty-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <prefix>${jar.folder.thirdparty}</prefix>
                <outputDirectory>${project.build.directory}/thirdparty-jars/</outputDirectory>
                <excludeGroupIds>com.mycompany</excludeGroupIds>
            </configuration>
        </execution>
        <execution>
            <id>build-mycompany-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <prefix>${jar.folder.mycompany}</prefix>
                <outputDirectory>${project.build.directory}/mycompany-jars/</outputDirectory>
                <includeGroupIds>com.mycompany</includeGroupIds>
            </configuration>
        </execution>
    </executions>
</plugin>

Note that I am using <excludeGroupIds>com.mycompany</excludeGroupIds> and <includeGroupIds> counterpart for differentiating between third party and company jars while copying them to different folders.

Next while adding these jars to the classpath property in manifest file inside jar, I want to append appropriate prefix directory to those classpaths. For example, I want to prefix third party jars with ../thirdparty-jars/, while prefix mycompany jars with ../mycompany-jars/.

For this I am using maven-antrun-plugin, something like this (this involves getting absolute path string of all dependencies and then running regex to trim prefix till target and then appending to it mycompany-jar or thirdparty-jar as required):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <id>concat-build-classpath</id>
            <phase>package</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <target>
                    <path id="master-classpath">
                        <fileset dir="${project.build.directory}/mycompany-jars/">
                            <include name="*.jar" />
                        </fileset>
                        <fileset dir="${project.build.directory}/thirdparty-jars/">
                            <include name="*.jar" />
                        </fileset>
                    </path>
                    <property name="absolute-path" value="${toString:master-classpath}" />
                    <loadresource property="relative-path">
                        <propertyresource name="absolute-path" />
                        <filterchain>
                            <tokenfilter>
                                <filetokenizer />
                                <replaceregex pattern="(^.*?target\\|(?&amp;lt;=;).*?target\\)" replace="" flags="g" />
                                <replaceregex pattern="(\\)" replace="/" flags="g" />
                                <replaceregex pattern="(thirdparty-jars)" replace="../thirdparty-jars" flags="g" />
                            </tokenfilter>
                        </filterchain>
                    </loadresource>
                    <jar destfile="${project.build.directory}/${project.build.finalName}.jar" basedir="src/main">
                        <manifest>
                            <attribute name="Class-Path" value="${relative-path}" />
                            <attribute name="Main-Class" value="com.mycompany.Application" />
                            <attribute name="Build-Jdk" value="${java.version}" />
                            <attribute name="Built-By" value="${user.name}" />
                        </manifest>
                    </jar>
                </target>
            </configuration>
        </execution>
    </executions>
</plugin>

We need to do this for many projects which have common parent pom. So, to avoid replicating this to all child poms, I moved this code to parent pom. But, somehow I am facing issue in executing maven-antrun-plugin jar task included in parent pom. Each time maven-jar-plugin jar task is getting executed from child. This I have discussed in this question.

Q1. My current question is is there any standard, more preferred approach to do this, may be to avoid maven-antrun-plugin and use maven-jar-plugin instead.

Q2. I have came across <classpathPrefix> as discussed under section "Altering The Classpath: Defining a Classpath Directory Prefix" here. But the issue is how can I run custom logic that I have implemented in maven-antrun-plugin with <classpathPrefix>. Does maven-jar-plugin provides capability something like this?

Mahesha999
  • 22,693
  • 29
  • 116
  • 189
  • For a more "standard" way I would need to understand your ultimate goal? Why do you separate the jars, why do you copy them to directories and why to you set classpath properties? – J Fabian Meier Feb 14 '18 at 12:14
  • @JFMeier Those are the questions I would have asked as well..? Why copying? Why creating a class-path in MANIFEST.MF file ? Are you trying to create executable jars? – khmarbaise Feb 14 '18 at 12:16
  • @JFMeier We want project jar to be very small. At deployment site, we will put all `mycompany` project dependencies and third party dependencies in separate folders (at paths I am trying populate in manifest in above code) only once. – Mahesha999 Feb 14 '18 at 12:58
  • Your jar is started from the command line, right? Then you can define a sh or bat file (depending on Linux/Windows) which starts java with your jar and the two directories on the classpath. – J Fabian Meier Feb 14 '18 at 13:09
  • @JFMeier @khmarbaise Yep you are right, but we want to add classpath to jar manifest, sort of default classpath. Should we not resort to this? Afterall `Class-Path` attribute of the jar manifest is [meant for this use only](https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Main_Attributes), right? And if this is the case, then there should be some standard way to add multiple paths to manifest `Class-Path` using maven, right? – Mahesha999 Feb 15 '18 at 06:03

0 Answers0