I would like to set up the maven java-docs plugin in my project to create an aggregated report that includes only some classes from some of the modules and output the report to a folder of choice.
I have already tried to work with the Maven documentation here however whats indicated there does not seem to work for me.
I have tried the following configuration in the past and ran it as:
mvn javadoc:javadoc, or even javadoc:aggregate with the following parent/child pom configurations:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.0</version>
<inherited>false</inherited>
<configuration>
<!-- Default configuration for all reports -->
</configuration>
<executions>
<execution>
<id>aggregate</id>
<goals>
<goal>aggregate</goal>
</goals>
<phase>package</phase>
<configuration>
</configuration>
</execution>
</executions>
</plugin>
I have used something like this in the past:
parent pom.xml
<pluginManagement>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</pluginManagement>
...
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<!-- Default configuration for all reports -->
</configuration>
<executions>
<execution>
<id>aggregate</id>
<goals>
<goal>aggregate</goal>
</goals>
<phase>site</phase>
<configuration>
<skip>false</skip>
</configuration>
</execution>
</executions>
</plugin>
</build>
Desired child module pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<skip>false</skip>
<noqualifier>all</noqualifier>
<sourceFileIncludes>
<include>**\/\Class1.java</include>
<include>**\/\Class2.java</include>
<include>**\/\Interface3.java</include>
<include>**\/\Class4.java</include>
</sourceFileIncludes>
<reportOutputDirectory>${project.parent.basedir}/..</reportOutputDirectory>
<destDir>java-docs</destDir>
</configuration>
</plugin>
</plugins>
</build>
This configuration works fine if I am only generating from one single module, however once another child module is picked and configured as the one shown before, running mvn javadoc:aggregate continues to generate the docs for module 1 only, and module 2 gets ignored(or maybe even overriden)
Has anyone worked with a similar scenario, a multi module project structured like so:
ParentFolder
. . . module1
pom.xml
. . . module3
pom.xml
. . . module4
pom.xml
pom.xml
and have succeeded generating an aggregated java docs report using the maven java docs plugin, while excluding some classes and outputting the results to a folder of their choice?
Any help with this would be greatly appreciated!
Do you have one parent POM that contains both plugin config for the child POMs, and module definitions? If so, you may want to consider separating this POM into a separate aggregator (module definitions) and parent (anything else in the current POM that should be shared with children).
This answer goes into a lot more detail about Maven build order and why the behavior occurs.
The aggregator POM will also hold the configuration for child module data that should be aggregated, such as Javadoc.
Related
I am working on a Java EE project that consists of a parent project, and a list of sub-projects (modules). I have declared and configured a plug-in on the parent project's pom.xml within a <pluginmanagement> tag as follows:
Parent pom.xml
...
<pluginManagement>
<plugins>
<!-- inmem-db-plugin -->
<plugin>
<groupId>com.btmatthews.maven.plugins.inmemdb</groupId>
<artifactId>inmemdb-maven-plugin</artifactId>
<version>${version.inmemdb-plugin}</version>
<inherited>true</inherited>
<executions>
<execution>
<id>runDB</id>
<goals>
<goal>run</goal>
</goals>
<configuration>
<monitorKey>inmemdb</monitorKey>
<monitorPort>11527</monitorPort>
<daemon>true</daemon>
<type>derby</type>
<database>localDB</database>
<username>${user}</username>
<password>${pass}</password>
<sources>
<script>
<sourceFile> create - data.sql </sourceFile>
<sourceFile> create - table.sql </sourceFile>
</script>
</sources>
</configuration>
</execution>
<execution>
<id>stopDB</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
...
And then I have referenced it on the child's pom.xml file:
...
<build>
<plugins>
<plugin>
<groupId>com.btmatthews.maven.plugins.inmemdb</groupId>
<artifactId>inmemdb-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
...
From what I have read on the internet, this seems to be the right way of making sure that the specific plug-in will be used only on the specific module that i have referenced it.
But, When I run the mvn install command, the plug-in that it is needed to run wont show up at all. Is there anything else that it is needed to be done, in order for the plug-in to run on a spesific module only?
Thanks in advance.
UPDATE: I replaced the wrong <phase> values with valid ones, but still when I enclose the plugin with <pluginmanagement> the plugin wont run at all.
The parent > child configuration looks correct i.e. define the plugin in pluginManagement in the parent and then engage it in the child by including it build/plugins. But this looks incorrect to me: <phase>pre-test</phase>, pre-test is not a valid phase in the Maven lifecycle and hooking your plugin up to a non existent phase will prevent it from being run. I think the correct plugin configuration is:
<plugin>
<groupId>com.btmatthews.maven.plugins.inmemdb</groupId>
<artifactId>inmemdb-maven-plugin</artifactId>
<version>${version.inmemdb-plugin}</version>
<inherited>true</inherited>
<executions>
<execution>
<id>runDB</id>
<goals>
<goal>run</goal>
</goals>
<configuration>
...
</configuration>
</execution>
</executions>
</plugin>
I suspect you might have been using the 'phases' pre-test and post-test to start and stop the in-memory DB as/when your test phase starts and stops? If so, then the correct Maven phases are:
pre-integration-test
post-integration-test
I have a maven model project, where I am generating jaxb class by maven command - clean install
and the jaxb classes are generated under target folder and jar file is generating under .m2 repository folder.
Now on my other project adding this jar as a dependency with proper group id and artifactId.
But I am getting ClassNotFoundException and compile error for those generated jaxb classes.
I am updating my question to add more details.
The Pom File of Model Project.
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.3</version>
<executions>
<execution>
<id>spf-ssp-generate</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generateDirectory>${project.build.directory}/jaxbclasses/pqr/xyz</generateDirectory>
<generatePackage>abc.vo.apply.v1</generatePackage>
<schemaIncludes>
<include>MyXSD.xsd</include>
</schemaIncludes>
</configuration>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/resources</schemaDirectory>
<extension>true</extension>
<args>
<arg>-XtoString</arg>
<arg>-Xequals</arg>
<arg>-XhashCode</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.6.4</version>
</plugin>
</plugins>
</configuration>
</plugin>
</plugins>
</build>
On clean install it generates the class files under.
target
jaxbclasses
pqr
xyz
with the package name - abc.vo.apply.v1
I have another Two Maven project(jar), suppose as, A & B.
Now I can use the jaxb model project as a maven dependency, and it compile fine.
Now My Web project is not a Maven project - it is a Liferay based on Ant.
I manually copy the A, B and The Jaxb Model project in to lib folder.
It compile fines. but I am getting ClassNotFoundException.
I am adding another answer, which I think is more accurate.
In order to make your JAXB project compile, I had to add this dependency:
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.6.5</version>
</dependency>
which obviously won't be automatically part of your classpath for Liferay.
When I ran mvn dependency:list, I got this:
org.jvnet.jaxb2_commons:jaxb2-basics-tools:jar:0.6.4:compile
org.jvnet.jaxb2_commons:jaxb2-basics:jar:0.6.4:compile
commons-lang:commons-lang:jar:2.2:compile
commons-logging:commons-logging:jar:1.1.1:compile
com.google.code.javaparser:javaparser:jar:1.0.8:compile
org.jvnet.jaxb2_commons:jaxb2-basics-runtime:jar:0.6.4:compile
commons-beanutils:commons-beanutils:jar:1.7.0:compile`
which means that you need to put these in the lib directory of your Liferay installation as well.
This is most likely due to the fact that the target directory is never included in the jar file by default. Try configuring the JAXB classes to be generated under (say) target/generated. Then, add this to the build plugin section of the POM:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>add-java-sources</id>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
I have a multi-module maven project with parent POM. One child of project is customized for different environments by profiles and parent pom also build needed modules depending on selected environment (profile).
I want to prevent building (read as "to run mvn package" in child module) customized child project without profile activated, because there is no "generic" or "default" version for environment. Another words, I want to force developer to use environment-dependent profile.
Is it possible to do so?
Maven Enforcer is made just for this requirement. Simply add the required profiles.
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>enforce-all-profiles-are-activated</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireActiveProfile>
<profiles>first,second</profiles>
</requireActiveProfile>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
I have an aggregator project built in jenkins and I want to publish javadocs. So I installed javadoc plugin and changed my parent pom as follows:
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<aggregate>true</aggregate>
<outputDirectory>${project.build.directory}/apidocs</outputDirectory>
</configuration>
I tried different configurations but this is the only one that won't fail the build. With this configuration the build doesn't fail but no javadocs are to be found. Am I missing something here? Does anyone has the same problem?
First you should use the aggregate goal instead of the parameter cause it's marked deprecated.
Furthermore you should configure javadoc plugin like the following in your root pom like this:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<!-- Default configuration for all reports -->
...
</configuration>
<executions>
<execution>
<id>aggregate</id>
<goals>
<goal>aggregate</goal>
</goals>
<phase>package</phase>
<configuration>
<!-- Specific configuration for the aggregate report -->
...
</configuration>
</execution>
...
</executions>
</plugin>
...
</plugins>
</build>
...
</project>
Afterwards you should be able just by:
mvn clean package
This will result in a folder in the root target/apidoc which contains the created aggregated javadocs.
I found a way to publish the javadocs as .jar. I used the above pom configuration with the small change:
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
It publishes javadocs as .jars for every sub-module. The javadocs are to be found in the sub-module directory not in the parent directory.
In a multi-module project, how can you specify that you want to execute a plugin goal in all the child-modules, but not on the parent project? There is <pluginManagement>, but that only defines the configuration for the execution -- the child modules would still need to reference the plugin to get the goal executed:
[...] However, this only configures plugins that are actually referenced within the plugins element in the children. (POM Reference)
Any other way to achieve this?
UPDATE: I've tried this according to Pascal's advice:
<!-- ... -->
<packaging>pom</packaging>
<modules>
<module>child</module>
</modules>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<!-- ... -->
This will still generate a .jar for the parent project, even though the jar goal is bound to the integration-test phase.
According to the Default Lifecycle Bindings, the bindings for a packaging pom are:
Default Lifecycle Bindings - Packaging
pom
package site:attach-descriptor
install install:install
deploy deploy:deploy
So if your parent POM has a <packaging>pom<packaging> (this should be the case as pointed out in a comment) and if you bind your plugins to other phases than those above (see the Lifecycle Reference for a comprehensive list), they won't be executed during the build of the parent POM.
(EDIT: My initial answer is just wrong. If you bind a plugin goal to a particular phase, it will be triggered during that phase, regardless of the packaging of the project. The Default Lifecycle Bindings don't have anything to do with that, they are just default lifecycle bindings. All what matters is if the phase to which the plugin is bound is part of the build lifecyle.)
As you pointed out, you can use the pluginManagement in the parent pom for the configuration of the plugin but if you really want to execute a plugin goal in children modules and not in the parent (you might have good reasons to do this but most of time, plugins won't have much effet on a module with a pom packaging that doesn't have any content), you'll have to reference plugins in the plugins element in the children.
Applied to your example, the parent pom.xml could define the following specifications:
<project>
<packaging>pom</packaging>
...
<modules>
<module>child</module>
</modules>
...
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>my-execution-id</id>
<phase>integration-test</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</pluginManagement>
</build>
...
</project>
And in every child pom.xml, only the following is required:
<project>
...
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
</plugins>
...
</build>
</project>
The described solution with plugin management is certainly correct, but in certain cases it does not fit. Suppose you would like to run several jar:jar goals in the child module each configured with its own settings (configuration) per execution. Or in general, when you don't want to force child poms to explicitly trigger the plugin(s).
In this case the solution that worked for me was to define the executions in the parent pom under a specific profile, and have it activated only in child poms for example by checking for existence of some file or property:
<profile>
<id>generate-dc</id>
<activation>
<file>
<exists>src/main/assembly/some.xml</exists>
</file>
</activation>
Then plugins won't be executed in the parent, but will be executed in all children if those contain the file, or set some property.
I had a similar requirement to run some plugins in the child but not the parent POM. i achieved this by stating <skip>true</skip> in the parent POM.
The parent pom entry is below:
<plugin>
<groupId>eviware</groupId>
<artifactId>maven-soapui-plugin</artifactId>
<version>4.0.0</version>
<inherited>false</inherited>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
</dependency>
</dependencies>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
The child project pom entry is below
<plugins>
<plugin>
<groupId>eviware</groupId>
<artifactId>maven-soapui-plugin</artifactId>
<version>4.0.0</version>
<configuration>
<settingsFile>site-service-web/src/test/soapui/soapui-settings.xml</settingsFile>
<projectFile>site-service-web/src/test/soapui/PodifiSite-soapui-project.xml</projectFile>
<outputFolder>site-service-web/target/surefire-reports</outputFolder>
<junitReport>true</junitReport>
<exportwAll>true</exportwAll>
<printReport>true</printReport>
</configuration>
</plugin>
</plugins>
This below config worked for me. Add the plugin in both the parent and child pom.
Parent :
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<inherited>true</inherited>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
Child
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<inherited>false</inherited>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
I tried the answer from Pascal but it did not work for me. The plugins referenced in the child pom did not execute, I'm assuming because they did not have a build phase binding.
The post here describes a solution that works by binding the plugins to execution ids and build phases: How to override default binding to phase of a Maven plugin
I'd recommend that to anyone else trying to get this working.
Use <inherited>false</inherited> under the plugins section in the parent project.
Plese refer to this page for more information.