Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven include JavaDoc Jar in Assembly

I have a project with multiple modules, including on that is responsible for building the final assembly from the artifacts of the other modules. As part of the assembly, I want to include the JavaDocs for two of the other modules. I have updated the pom files for those modules to generate the JavaDoc JAR files, and modified the assembly project to list those JavaDoc Jar files as dependencies. However, when I build the project from the top level, the assembly project tells me that it cannot find the javaDoc jars. If I install all the other modules first, then build the assembly module directly, the assembly will build fine.

How can I get the assembly to build correctly, with all the specified dependencies, when run from the top level project?

Edited to add more info at the request of the responders:

Here's a simplified project I threw together to demonstrate the issue. The directory layout is as follows:

sample/
  \--pom.xml
  \--module1/
       \--pom.xml
       \--src/ 
            \--{the usual main/java layout with a single java file, with javadocs}
  \--package/
       \--pom.xml
       \--assemblies/
            \--bin.xml

The top level pom.xml, under sample, looks like this:

<?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/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>test</groupId>
  <artifactId>project</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <modules>
    <module>module1</module>
    <module>package</module>
  </modules>

  <build>
    <defaultGoal>package</defaultGoal>
  </build>
</project>

The module1 pom.xml is a basic project file with an entry for the javadoc plugin:

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>test</groupId>
  <artifactId>module1</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        <version>2.6</version>
        <executions>
          <execution>
            <id>javadoc-jar</id>
            <phase>package</phase>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

The package module pom file specifies dependencies on the module1 Jar file and the module1 JavaDoc jar file:

<?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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <!-- The Basics -->
  <groupId>test</groupId>
  <artifactId>packaging</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <!-- Shared Dependencies -->
  <dependencies>
    <dependency>
      <groupId>test</groupId>
      <artifactId>module1</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

    <dependency>
      <groupId>test</groupId>
      <artifactId>module1</artifactId>
      <version>1.0-SNAPSHOT</version>
      <classifier>javadoc</classifier>
    </dependency>
  </dependencies>

  <!-- Build Settings -->
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.2-beta-4</version>
        <configuration>
          <descriptors>
            <descriptor>assemblies/bin.xml</descriptor>
          </descriptors>
        </configuration>

        <executions>
          <execution>
            <id>make-assembly</id> <!-- this is used for inheritance merges -->
            <phase>package</phase> <!-- append to the packaging phase. -->
            <goals>
              <goal>single</goal> <!-- goals == mojos -->
            </goals>
          </execution>
        </executions>

      </plugin>

    </plugins>
  </build>

</project>

And finally, the assembly file includes the two dependencies, with the JavaDoc jar file being stored unpacked into the assembled file. I have each dependencySet use strict Filtering to highlight the inability of the assembly plugin to find the specified files.

<assembly>
  <id>bin</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>

  <dependencySets>
    <dependencySet>
      <excludes>
        <!-- Exclude the Jars that are included in later sections -->
        <exclude>test:module1:jar:javadoc</exclude>
      </excludes>
      <outputDirectory>lib</outputDirectory>
      <unpack>false</unpack>
      <useTransitiveDependencies>true</useTransitiveDependencies>
      <useTransitiveFiltering>false</useTransitiveFiltering>
      <useProjectArtifact>false</useProjectArtifact>
    </dependencySet>

    <dependencySet>
      <includes>
        <include>test:module1:jar:javadoc</include>
      </includes>
      <outputDirectory>docs</outputDirectory>
      <unpack>true</unpack>
      <useTransitiveDependencies>true</useTransitiveDependencies>
      <useProjectArtifact>false</useProjectArtifact>
      <useStrictFiltering>true</useStrictFiltering>
    </dependencySet>
  </dependencySets>
</assembly>

Running this project from the top results in the following output:

[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   Unnamed - test:module1:jar:1.0-SNAPSHOT
[INFO]   Unnamed - test:packaging:pom:1.0-SNAPSHOT
[INFO]   Unnamed - test:project:pom:1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] Building Unnamed - test:module1:jar:1.0-SNAPSHOT
[INFO]    task-segment: [clean, package]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] Deleting directory /Users/john/Documents/src/workspace/sample/module1/target
[INFO] [resources:resources]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:compile]
[INFO] Compiling 1 source file to /Users/john/Documents/src/workspace/sample/module1/target/classes
[INFO] [resources:testResources]
[WARNING] Using platform encoding (MacRoman actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/john/Documents/src/workspace/sample/module1/src/test/resources
[INFO] [compiler:testCompile]
[INFO] No sources to compile
[INFO] [surefire:test]
[INFO] No tests to run.
[INFO] [jar:jar]
[INFO] Building jar: /Users/john/Documents/src/workspace/sample/module1/target/module1-1.0-SNAPSHOT.jar
[INFO] [javadoc:jar {execution: javadoc-jar}]
[WARNING] Source files encoding has not been set, using platform encoding MacRoman, i.e. build is platform dependent!
Loading source files for package test...
Constructing Javadoc information...
Standard Doclet version 1.5.0_20
Building tree for all the packages and classes...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/test//AClass.html...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/test//package-frame.html...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/test//package-summary.html...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/test//package-tree.html...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/constant-values.html...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/test/class-use//AClass.html...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/test//package-use.html...
Building index for all the packages and classes...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/overview-tree.html...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/index-all.html...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/deprecated-list.html...
Building index for all classes...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/allclasses-frame.html...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/allclasses-noframe.html...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/index.html...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/help-doc.html...
Generating /Users/john/Documents/src/workspace/sample/module1/target/apidocs/stylesheet.css...
[INFO] Building jar: /Users/john/Documents/src/workspace/sample/module1/target/module1-1.0-SNAPSHOT-javadoc.jar
[INFO] ------------------------------------------------------------------------
[INFO] Building Unnamed - test:packaging:pom:1.0-SNAPSHOT
[INFO]    task-segment: [clean, package]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] Deleting directory /Users/john/Documents/src/workspace/sample/package/target
[INFO] [site:attach-descriptor]
[INFO] [assembly:single {execution: make-assembly}]
[INFO] Reading assembly descriptor: assemblies/bin.xml
[WARNING] The following patterns were never triggered in this artifact exclusion filter:
o  'test:module1:jar:javadoc'

[WARNING] The following patterns were never triggered in this artifact inclusion filter:
o  'test:module1:jar:javadoc'

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] : org.apache.maven.plugin.assembly.model.Assembly@139c27
Assembly is incorrectly configured: bin

Assembly: bin is not configured correctly: One or more filters had unmatched criteria. Check debug log for more information.
[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12 seconds
[INFO] Finished at: Wed Oct 07 15:23:26 PDT 2009
[INFO] Final Memory: 26M/52M
[INFO] ------------------------------------------------------------------------

I have posted this project for download.

like image 458
John Haager Avatar asked Oct 07 '09 21:10

John Haager


2 Answers

Figured out a solution that seems like it works (at least on the sample app I posted). I modified the inclusion/exclusion entries in the assembly file to wildcard just the type, and the assembly now behaves exactly as expected. The JavaDoc JAR file is not placed in the lib directory, and the JavaDocs are unpacked as intended.

The final assembly file is as follows:

<assembly>
  <id>bin</id>
  <formats>
 <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>

  <dependencySets>
    <dependencySet>
      <excludes>
        <!-- Exclude the Jars that are included in later sections -->
        <exclude>test:module1:*:javadoc</exclude>
      </excludes>
      <outputDirectory>lib</outputDirectory>
      <unpack>false</unpack>
      <useTransitiveDependencies>true</useTransitiveDependencies>
      <useTransitiveFiltering>false</useTransitiveFiltering>
      <useProjectArtifact>false</useProjectArtifact>
    </dependencySet>

    <dependencySet>
      <includes>
        <include>test:module1:*:javadoc</include>
      </includes>
      <outputDirectory>docs</outputDirectory>
      <unpack>true</unpack>
      <useTransitiveDependencies>true</useTransitiveDependencies>
      <useProjectArtifact>false</useProjectArtifact>
      <useStrictFiltering>true</useStrictFiltering>
    </dependencySet>
  </dependencySets>
</assembly>

Update: Some quick testing has revealed that the type of JavaDoc Jar files, at least when referenced from a full build, is 'javadoc'. However, when the package module is run stand-alone, that type is not recognized and cannot be retrieved from the local repository. So, it seems that in order to get both build modes (as part of the overall build, and when built independently), you have to wildcard the type for the JavaDoc Jar files in the assembly.

like image 93
John Haager Avatar answered Sep 27 '22 21:09

John Haager


There is a problem with the test:module1:jar:javadoc identity pattern used for exclusion and inclusion of dependencies in both <dependencySet> as shown by in the build failure trace:

[WARNING] The following patterns were never triggered in this artifact exclusion filter:
o  'test:module1:jar:javadoc'

[WARNING] The following patterns were never triggered in this artifact inclusion filter:
o  'test:module1:jar:javadoc'

To be honnest, I can't see what's wrong with the test:module1:jar:javadoc pattern: it follows the groupId:artifactId:type[:classifier] format and looks absolutely fine to me (could this be a bug?). But the fact is that it doesn't match any dependency and this causes two problems:

  1. the javadoc jar isn't excluded and will end up in lib beside the other jar,
  2. nothing is found to be unpacked into docs and this makes the build fail.

Actually, the only way I found to get the whole stuff working is to use a pattern with a wildcard (more precisely *:javadoc). Below an updated assembly descriptor:

<assembly>
  <id>bin</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>

  <dependencySets>
    <dependencySet>
      <excludes>
        <!-- Exclude the Jars that are included in later sections -->
        <exclude>*:javadoc</exclude>
      </excludes>
      <outputDirectory>lib</outputDirectory>
      <unpack>false</unpack>
      <useTransitiveDependencies>true</useTransitiveDependencies>
      <useTransitiveFiltering>false</useTransitiveFiltering>
      <useProjectArtifact>false</useProjectArtifact>
    </dependencySet>

    <dependencySet>
      <includes>
        <include>*:javadoc</include>
      </includes>
      <outputDirectory>docs</outputDirectory>
      <unpack>true</unpack>
      <useTransitiveDependencies>true</useTransitiveDependencies>
      <useProjectArtifact>false</useProjectArtifact>
      <useStrictFiltering>true</useStrictFiltering>
    </dependencySet>
  </dependencySets>
</assembly>

Not sure this will be satisfying enough but at least, it's working and produces the expected result.

like image 31
Pascal Thivent Avatar answered Sep 27 '22 23:09

Pascal Thivent