views:

1300

answers:

2

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"&gt;

  <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"&gt;
  <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"&gt;
  <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.

+1  A: 

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.

Pascal Thivent
I've tried the wildcard approach you suggest, and, while the build process succeeds, the javadocs are still included in the lib/ directory and are not unpacked into the docs directory as expected.
John Haager
That's weird, very weird... I modified the sample project you provided and it's working on my machine (c) with maven 2.2.1 and the maven assembly plugin 2.2-beta-4: `module1-1.0-SNAPSHOT-javadoc.jar` isn't included in the `lib` directory (it contains only `module1-1.0-SNAPSHOT.jar`) and is unpacked into the `docs` directory of `packaging-1.0-SNAPSHOT-bin.jar`... Just in case, did you run `mvn clean` (this doesn't explain why javadocs aren't unpacked)?
Pascal Thivent
Do you still have warnings when the assembly module is built?
Pascal Thivent
BTW, I added a `<parent>` section to the `module1` and `packaging` poms but I don't think this changes anything.
Pascal Thivent
If I use the wildcard for the javadocs, I get no warnings, but I also do not get the desired behavior. This is starting to seem like a bug in Maven or something.
John Haager
There is something strange indeed and it might be a bug. I don't understand why I don't have the same behavior on my GNU/Linux machine though.
Pascal Thivent
+1  A: 

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.

John Haager
Just verified that making the same change in my real application also fixes the behavior. My guess is that the type of the JavaDocs isn't 'jar', but something else. Kinda strange.
John Haager
I don't get how this differ from `*:javadoc`. I'm lost...
Pascal Thivent
I think the difference is that if you use <code>*:javadoc</code>, it looks for artifacts named <code>javadoc</code> in any group.
John Haager
That's not how I interpret http://www.sonatype.com/books/maven-book/reference/assemblies-sect-output-algorithm.html#assemblies-sect-fine-tune but you might be right. Interesting...
Pascal Thivent