How can I compile and run my Custom Doclet class i

2019-07-24 20:18发布

I'm trying to dump all class javadoc comment (preferabbly subclasses of a libraries WebPage class) at compile time into a .properties file in the format classname=comment.

So far I have:

  • created doclet class SiteMapDoclet
    • the class is defined to scan all the javadocs in the project and dump them to a .properties file
  • Added the necessary configs to my pom.xml for it to work.

Versions: Java 1.6.0.21, Maven 2.2.1

Problem:
mvn site returns:

Embedded error: Error rendering Maven report: 
Exit code: 1 - java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
    at us.ak.state.revenue.cssd.Personnel.utils.SiteMapDoclet.<clinit>(SiteMapDoclet.java:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)

I tried setting the jars as AdditionalDependencies even though they are normal dependencies for my project. I also tried adding the paths to the jars I expect my class to need as part of the bootclasspath.

the reporting section of my pom.xml looks like this:

<reporting>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-javadoc-plugin</artifactId>
      <version>2.9</version>
      <reportSets>
        <reportSet>
          <id>html</id>
          <reports>
            <report>javadoc</report>
          </reports>
        </reportSet>
        <reportSet>
          <id>siteMap</id>
          <configuration>
            <doclet>
              us.ak.state.revenue.cssd.Personnel.utils.SiteMapDoclet
            </doclet>
            <docletPath>${project.build.outputDirectory}</docletPath>
            <destDir>SiteMap</destDir>

            <author>false</author>
            <useStandardDocletOptions>false</useStandardDocletOptions>
            <!-- there has got to be a better way to do this! -->
            <!-- how can I fix the CSSD-Web - Base to use a proper manifest file? -->
            <bootclasspath>
              ${bootClassPath};
              ${env.CLASSPATH};
              ${m2Repository}/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar;
              ${m2Repository}/org/apache/wicket/wicket-core/${wicket.version}/wicket-core-${wicket.version}.jar;
              ${m2Repository}/us/ak/state/revenue/cssd/CSSD-Web/${CSSDWebBase.version}/CSSD-Web-${CSSDWebBase.version}.jar
            </bootclasspath>
            <additionalDependencies>
              <additionalDependency>
                <groupId>us.ak.state.revenue.cssd</groupId>
                <artifactId>CSSD-Web</artifactId>
                <version>${CSSDWebBase.version}</version>
              </additionalDependency>
              <additionalDependency>
                <groupId>org.apache.wicket</groupId>
                <artifactId>wicket-core</artifactId>
                <version>${wicket.version}</version>
              </additionalDependency>
              <additionalDependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.16</version>
              </additionalDependency>
              <additionalDependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.1.1</version>
              </additionalDependency>
            </additionalDependencies>

            <name>SiteMapDoclet</name>
            <description>Page Descriptions for SiteMap generation</description>
          </configuration>
          <reports>
            <report>javadoc</report>
          </reports>
        </reportSet>
      </reportSets>
    </plugin>
  </plugins>
</reporting>

NOTE:
${m2Repository} is defined as a property higher up the file,
defined as ${env.USERPROFILE}/.m2/repository
${bootClassPath} is defined as a property higher up the file,
defined as ${env.JRE_6_HOME}\lib\rt.jar;${env.JAVA_HOME}\lib\tools.jar;

How can i fix the NoClassDefFoundError?

Additionally I would like my SiteMap file to run as a part of the normal build process, after compile but before package.

I've tried defining this in build, but the javadoc doesn't get created and I don't see any logging output from my Doclet.

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>2.9</version>
    <executions>
      <execution>
        <id>build-siteMap-Descriptions</id>
        <phase>process-classes</phase>
      </execution>
    </executions>
  </plugin>

UPDATE:
Thanks to @ben75 's suggestion. I've removed the <reporting> section of my pom.xml and now have the process failing during build. I added <goals> and copied the <configuration> section from <reporting>.

It's still throwing the NoClassDefFoundError but it's happening on build where I want it to. I tried adding:

<includeDependencySources>true</includeDependencySources>
<dependencySourceIncludes>
  <dependencySourceInclude>org.apache.wicket:wicket-core:*</dependencySourceInclude>
  <dependencySourceInclude>org.apache.commons.logging:*</dependencySourceInclude>
  <dependencySourceInclude>us.ak.state.revenue.cssd:CSSD-Web:*</dependencySourceInclude>
</dependencySourceIncludes>

To the configuration section, but that didn't work.

2条回答
贼婆χ
2楼-- · 2019-07-24 20:31

Building upon @ben75s Excellent Advice I was able to get it to finally run.
This "works". It feels wrong and I'd love to see a better method.

Here's what I did:

  • Defined the plugin in the build section with the javadoc goal.
    • made sure tools.jar and rt.jar are in the <bootclasspath>
    • defined the <docletPath> as \;.;${project.build.outputDirectory};
      • the \;.; are necessary because maven doesn't append correctly
      • also had to explicitly add the path to some of the packages here to prevent inheritence of conflicting versions. (Specifically of Log4J)
    • defined <docletArtifacts> with the packages for the classes throwing the NoClassDefFoundError

My plugin now looks like this:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>2.9</version>
    <executions>
      <execution>
        <id>build-siteMap-Descriptions</id>
        <phase>process-classes</phase>
        <goals>
          <!--<goal>aggregate</goal>-->
          <goal>javadoc</goal>
        </goals>
        <configuration>
          <doclet>
            us.ak.state.revenue.cssd.Personnel.utils.SiteMapDoclet
          </doclet>
          <!-- the initial '\;.;' is required
               because maven doesn't separate the path statements properly

               The 5 packages are necessary
               because otherwise slf4j complains about multiple bindings
          -->
          <docletPath>
            \;.;${project.build.outputDirectory};
            ${m2Repository}/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar;
            ${m2Repository}/log4j/log4j/1.2.16/log4j-1.2.16.jar;
            ${m2Repository}/log4j/apache-log4j-extras/1.1/apache-log4j-extras-1.1.jar;
            ${m2Repository}/us/ak/state/revenue/cssd/CSSD-Web/${CSSDWebBase.version}/CSSD-Web-${CSSDWebBase.version}.jar;
            ${m2Repository}/org/apache/wicket/wicket-core/${wicket.version}/wicket-core-${wicket.version}.jar;
            ${m2Repository}/org/apache/wicket/wicket-util/${wicket.version}/wicket-util-${wicket.version}.jar;
          </docletPath>
          <docletArtifacts>
            <!--
            <docletArtifact>
              <groupId>commons-logging</groupId>
              <artifactId>commons-logging</artifactId>
              <version>1.1.1</version>
            </docletArtifact>
            -->
            <docletArtifact>
              <groupId>org.slf4j</groupId>
              <artifactId>slf4j-log4j12</artifactId>
              <version>1.6.2</version>
            </docletArtifact>
            <!-- how do I fix the download errors? -->
            <!--
            <docletArtifact>
              <groupId>org.slf4j</groupId>
              <artifactId>slf4j-api</artifactId>
              <version>1.6.2</version>
            </docletArtifact>
            -->
            <!--
            <artifact>
              <groupId>log4j</groupId>
              <artifactId>log4j</artifactId>
              <version>1.2.16</version>
            </artifact>
            -->
            <!--
            <docletArtifact>
              <groupId>log4j</groupId>
              <artifactId>apache-log4j-extras</artifactId>
              <version>1.1</version>
            </docletArtifact>
            <docletArtifact>
              <groupId>us.ak.state.revenue.cssd</groupId>
              <artifactId>CSSD-Web</artifactId>
              <version>${CSSDWebBase.version}</version>
            </docletArtifact>
            <docletArtifact>
              <groupId>org.apache.wicket</groupId>
              <artifactId>wicket-core</artifactId>
              <version>${wicket.version}</version>
            </docletArtifact>
            -->
          </docletArtifacts>

          <!-- the initial '\;.;' is required
               because maven doesn't separate the path statements properly -->
          <bootclasspath>
            \;.;
            ${bootClassPath};
            ${env.CLASSPATH};
          </bootclasspath>

          <destDir>SiteMap</destDir>

          <author>false</author>
          <!-- don't print the packages/classes it's running on -->
          <quiet>true</quiet>
          <debug>true</debug> <!-- save options -->
          <useStandardDocletOptions>false</useStandardDocletOptions>

          <name>SiteMapDoclet</name>
          <description>Page Descriptions for SiteMap generation</description>
        </configuration>
      </execution>
    </executions>
  </plugin>
查看更多
闹够了就滚
3楼-- · 2019-07-24 20:39

You can try to put your <additionalDependencies> as plugin dependendencies:

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-javadoc-plugin</artifactId>
      <version>2.9</version>
      <dependencies>
         <dependency>
            <groupId>us.ak.state.revenue.cssd</groupId>
            <artifactId>CSSD-Web</artifactId>
            <version>${CSSDWebBase.version}</version>
         </dependency>
         ...

To attach javadoc plugin to your normal build process, I think you just need to specify the goal and preferably attaching it to prepare-package phase (so that javadoc is not generated when you simply run the test phase):

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>2.9</version>
            <executions>
                <execution>
                    <id>attach-javadoc</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
查看更多
登录 后发表回答