1

Currently, I have a pom.xml, which, upon build, gathers dependency Javadoc jars from mvnrepository and unpacks them in specific folders:

    <build>
        <finalName>${parent.artifactId}</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>unpack-javadoc-jars</id>
                        <goals>
                            <goal>unpack</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <artifactItems>
                        <artifactItem>
                            <groupId>groupid1</groupId>
                            <artifactId>artifactid1</artifactId>
                            <version>1.0.0</version>
                            <classifier>javadoc</classifier>
                            <outputDirectory>${project.build.directory}/dependency-javadoc/artifactid1-1.0.0</outputDirectory>
                        </artifactItem>
                        <artifactItem>
                            <groupId>groupid2</groupId>
                            <artifactId>artifactid2</artifactId>
                            <version>2.0.0</version>
                            <classifier>javadoc</classifier>
                            <outputDirectory>${project.build.directory}/dependency-javadoc/artifactid2-2.0.0</outputDirectory>
                        </artifactItem>
    ...
                        </artifactItems>
                </configuration>
            </plugin>
        </plugins>
    </build>

The thing is, if I do not specify the output directory field for each artifact, the javadoc gets unpacked all in one folder (which is also configurable for the unpack goal - https://maven.apache.org/plugins-archives/maven-dependency-plugin-2.6/unpack-mojo.html ), and I want them to be clearly structured in folders. So I added a directory entry for each artifactItem. However, I have to write the folder name manually. Is there a way to refer the existing artifactItem's fields, in a way similar to this:

                        <artifactItem>
                            <groupId>groupid1</groupId>
                            <artifactId>artifactid1</artifactId>
                            <version>1.0.0</version>
                            <classifier>javadoc</classifier>
                            <outputDirectory>${project.build.directory}/dependency-javadoc/${artifactItem.artifactId}-${artifactItem.version}</outputDirectory>
                        </artifactItem>

This way,I will be able to just copy/paste the outputDirectory in all javadoc artifact entries, but it will be the same. Thanks!

Umair Mubeen
  • 823
  • 4
  • 22
  • Why unpacking javadoc during a build? that is usually done by your IDE whereas usually an IDE uses the source packages? – khmarbaise Aug 07 '20 at 13:19
  • I am maintaining a project which uses open source libraries, and I have to have the javadoc handy. Basically,we just have to have available javadoc for every used component, and it has to be as automatic during build as possible. An alternative solution would be to copy the javadoc jars instead of unpacking them,but I'd like to see first if it can work this way. – Velitchko Valkov Aug 07 '20 at 18:12
  • 1
    If your IDE is configured correctly it will download the source/javadoc automatically by looking into the appropriate library and it does not make sense to unpack them during a build. Let your IDE do the work https://stackoverflow.com/questions/31072667/how-to-force-intellij-to-download-javadocs-with-maven (Eclipse can be configured as well ..) – khmarbaise Aug 08 '20 at 09:15

1 Answers1

1

This is an interesting question. I remember having had this requirement of using POM declarations as properties in the same POM in the past, but I hardcoded the values then since there were just a few of them. However, I think we're out of luck here. At least with the approach that came into my mind first:

Writing a Maven Plugin like e.g POM Strings Maven Plugin (and in fact I did that here for a POC of my idea) with a goal:

pom-strings:toProperties -Dxpath=//artifactItems/*/text()[normalize-space()]

which finds all XML text nodes (under <artifactItems> in your case) in the POM, then finds their full XML tree paths and creates Maven project properties for them that look like:

/project/build/plugins/plugin/configuration/artifactItems/artifactItem/artifactId=...
/project/build/plugins/plugin/configuration/artifactItems/artifactItem/version=...

After declaring its execution at e.g. the initialize phase of your projects your declarations will look like (with line breaks for easier reading):

<outputDirectory>
${project.build.directory}/dependency-javadoc/
${/project/build/plugins/plugin/configuration/artifactItems/artifactItem/artifactId}
-
${/project/build/plugins/plugin/configuration/artifactItems/artifactItem/version}
</outputDirectory>

The problem, however, is this inconspicuous, innocent "...", since the full paths are not unique in this case. There are two possible values for each of them. To resolve this a key would have to be introduced (by finding the first unique parent) so that the properties will look like:

/project/build/plugins/plugin/configuration/artifactItems[<key1>]/artifactId=artifactid1
/project/build/plugins/plugin/configuration/artifactItems[<key1>]/version=1.0.0
/project/build/plugins/plugin/configuration/artifactItems[<key2>]/artifactId=artifactid2
/project/build/plugins/plugin/configuration/artifactItems[<key2>]/version=2.0.0

If this key would be a numerical index the declaration order would be crucial, which contradicts the declarative nature of POMs and for that it's not the Good, but the Bad and the Ugly[1]:

/.../artifactItems[0]/artifactId=artifactid1
/.../artifactItems[0]/version=1.0.0
/.../artifactItems[1]/artifactId=artifactid2
/.../artifactItems[1]/version=2.0.0

If this key would be an associative textual key, the question is which value should be taken and if this is decidable somehow you would have to do what you wanted to avoid originally: hardcode the <artifactId>s (or <version>s, or whatever ensures uniqueness):

/.../artifactItems['artifactid1']/artifactId=artifactid1
/.../artifactItems['artifactid1']/version=1.0.0
/.../artifactItems['artifactid2']/artifactId=artifactid2
/.../artifactItems['artifactid2']/version=2.0.0
Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
  • Thank you very much for your comment. I guess that there is no natural built-in mechanism for such a referral, so only an additional plugin could be of use. I'll have to evaluate whether the overhead would be worth not writing the properties manually (there are ~50 open source jars). – Velitchko Valkov Aug 10 '20 at 07:46
  • @VelitchkoValkov The above is not just a comment, but an answer. (And, hence, can be [upvoted and even accepted](https://stackoverflow.com/help/why-vote). ;) – Gerold Broser Aug 10 '20 at 09:33