Maven maven-glassfish-plugin in a multiproject setup - maven

Short version:
I would like the maven-glassfish-plugin to only be executed in the root project in a hierarchical (inheritance based) maven multiproject setup.
Long version:
Following setup:
project-root
|
+-pom.xml
|
+ ear-module
| |
| +-pom.xml
|
+ jar-module
|
+-pom.xml
All submodules are included in the root project via <modules>...</modules> and all submodules inherit the root project pom.xml.
In my root project pom I include the maven-glassfish-plugin:
...
<plugin>
<groupId>org.glassfish.maven.plugin</groupId>
<artifactId>maven-glassfish-plugin</artifactId>
<version>2.1</version>
<inherited>false</inherited>
<configuration>
<glassfishDirectory>${glassfish.home}</glassfishDirectory>
<passwordFile>${glassfish.home}/masterpassword.txt</passwordFile>
<domain>
<name>${project.name}</name>
<adminPort>4848</adminPort>
<httpPort>8080</httpPort>
<httpsPort>8443</httpsPort>
<iiopPort>3700</iiopPort>
<jmsPort>7676</jmsPort>
</domain>
<components>
<component>
<name>poc.vermittler</name>
<artifact>${project.basedir}/ear-module/target/ear-project-1.0-SNAPSHOT.ear</artifact>
</component>
</configuration>
</plugin>
...
(Note: This is just an simplified version of my pom. It may not run :)
I want to only deploy the ear-module module to glassfish, this is why I added <inherited>false</inherited> section, and depict the modules to be deployed as <components>...</components> in the root pom.
Now the command:
mvn glassfish:deploy
Will deploy the ear to glassfish, all well so far... but then maven will decent recursively to all submodules, which will all fail with:
No plugin found for prefix 'glassfish' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories
I could tell maven to only run the root project with the -pl option but for my gusto, deploying shouldn't rely on such additional information.
Thanks a lot for your help!

It seems that there is no good solution to this problem:
either the plugin supports a "NOP"/silent discard functionality
or it will fail in all subprojects
Another method could be to create a new subproject (which is not included in the root project by <modules>...</modules> but inherits from the root project) and add dependencies to only the projects that have a deployment artifact.
The plugin can now be included in this subproject without it wanting to run any subproject.
Or for anybody who is lazy: mvn clean package glassfish:redeploy -pl . to selectively only run the root project without descending into child projects.

Related

Maven plugin crashes when modules are not specified

The Maven plugin goal database:run crashes when I try to run it without specifying the modules where it's defined.
My project has four modules (main, core, cli, and web) and I added a database plugin only in two of them (cli and web), in the standard form:
<plugin>
<groupId>org.tools.database</groupId>
<artifactId>database-maven-plugin</artifactId>
<version>1.0.3</version>
<configuration>
...
</configuration>
</plugin>
It works well when I run:
mvn -pl cli,web database:run
But crashes if I omit the module's list:
mvn database:run
No plugin found for prefix 'database' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories...
Do I need to also define the plugin it in the main module/project, so it doesn't crash? But it wouldn't make sense... would it? Is this the expected behavior? I would prefer the shorter command line, if possible.

Can a maven build tell if it is multi-module

I have a multi-module maven build, with a structure like
a/
pom.xml
b/
pom.xml
c/
pom.mxl
d/pom.xml
e/
pom.xml
Some of the analysis plugins are slow, so I would like to skip them when running building multiple modules (cd a; mvn install) but not a single module (cd a/b/c; mvn install). In the single module build, I might look at the generated warnings and fix them, but with the multi-module build, they I won't look at them, since the full build literally builds dozens of modules.
Is there a way to determine if I am building multiple modules from within the build?
I am hoping for something like reactor.build is defined in all modules when I run from /a but not defined when I run from /a/b/c.
All I was able to find when I googled was how to set up a multi-module build or only build some of the projects, which is not what I am looking for.
Goals
I understand the maven build cycle. I want to be able to add something like this to my pom root pom:
<properties>
<skipSlowPlugin>${multi.project.build}</skipSlowPlugin>
<properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.slow</groupId>
<artifactId>analysis-tool</artifactId>
<version>1.0.0</version>
<configuration>
<skip>${skipSlowPlugin}</skip>
</configuration>
</plugin>
</plugin>
</pluginManagement>
</build>
If I run the build from /a/b/c, multi.project.build will be false and the plugin will run. If I run from /a or /a/b, then multi.project.build will be true and the plugin will not run.
In every case, I want to build everything under the current directory, so --pm and --am are irrelevant.

Maven dependencies inside tar.gz file

So I have the following tar.gz file in my repo with structure as:
> A.tar.gz
> |
> |____ a.tar.gz
> |
> |____ b.tar.gz
> |
> |_____ folderA
> |
> |_____ folderB
> |
> |______ jar1.jar
> |
> |______ jar2.jar
Now in my POM file for another project I would like to add the jar1 and jar2 as dependencies. So far I have the following:
<dependency>
<groupId>com.groupid</groupId>
<artifactId>master</artifactId>
<version>18.1</version>
<type>tar.gz</type>
<classifier>bin</classifier>
</dependency>
This made the tar file available. I then tried to unpack as:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeTypes>tar.gz</includeTypes>
<includeArtifactIds>master</includeArtifactIds>
<outputDirectory>target/somefolder</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
However, on running the build, I still don't get the jars as dependencies. I am sure I am missing something , so any help appreciated!
So you have JAR dependencies located inside another tar.gz dependency that you want in your project. So far so good, the problem is you're trying to:
Make the the first .tar.gz dependency available (OK)
Launch the build to unpack the jars (OK)
Add unpacked jar as dependencies during the same build (Not possible)
All in one run. That is not possible in Maven by design (to the best of my knowledge). Even if you did find a way to do it this way, that would over-complexify your build and break Maven design, probably leading to other issues.
You mentioned that you don't control the packaging of the other team and it seems you can't upload said dependencies on a Nexus repo either. What you can do is make the JAR dependencies available in your local repo prior to running your build by doing something like:
Download your tar.gz file and unpack it
Install the jar dependencies in your local Maven repo using commands like mvn install:install-file -Dfile=path/to/jar1.jar -DgroupId=com.mycompany -DartifactId=jar1 -Dversion=1.0.0 -Dpackaging=jar with proper version, groupdId and artifactId for each jars (see the Guide to installing 3rd party JARs for more details)
Now you can run your your original project only by mentioning your jar dependencies as <dependency>
With this you will manually install your jar dependencies in your Maven local repository, rendering them available to your project without needing a Nexus repository or further unpackaging. You can perform step 1 and 2 manually or by creating another Maven project that you will have to run once before running your main project. To do so you can create a new project and use the maven-dependency-plugin as you already did coupled with the maven-exec-plugin to run the mvn install:install-file command.
Note this process must be done for every individual machine on which you will run your project. As #khmarbaise mentioned, it's best to have your dependencies available directly through a repository manager such as Nexus without having to perform additional steps, but this temporary workaround should work just fine.

What is the best place for JavaDoc files in a Maven project using Tomcat?

I am regularly deploying a Maven project to a Tomcat server, using Travis CI. My project is a web app, so I have configured my pom.xml for building a WAR file, instead of a JAR:
...
<packaging>war</packaging>
...
With Maven, I can generate a directory containing all the JavaDoc files for my project; Maven puts them in the target/site/apidocs directory. But then, when I deploy my project, Travis doesn't perform any mvn site phase so I don't have my JavaDocs on the server.
Should I edit my pom.xml so that Maven puts the JavaDoc files somewhere in the src directory (instead of target) or is there a way to package the JavaDoc files together with the WAR file? I thought that I could create a docs/ directory inside src/main/webapp/. Specifically: is it "good practice" to generate my JavaDoc in src instead of target? if not, how can I have a WAR file containing my JavaDoc?
What would you suggest is the best thing to do?
I already know how to generate a standalone JAR containing my JavaDoc files (see here), but this is not what I'm looking for.
Use the site plugin https://maven.apache.org/plugins/maven-site-plugin/ and the javdoc plugin https://maven.apache.org/plugins/maven-javadoc-plugin/usage.html.
Add the following to your pom.xml
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<links>
<link>http://commons.apache.org/lang/api</link>
<link>http://java.sun.com/j2se/1.5.0/docs/api</link>
<link>http://this-one-will-not-work</link>
</links>
</configuration>
</plugin>
</plugins>
</reporting>
then mvn site:site your documentation will be in target/site you can also deploy it.

Nexus staging Maven plugin on a complex Maven project?

I am trying to release several maven projects together, by deploying them to oss.sonatype.org, then releasing them to Maven central.
I have a build pom, that I use to build several multi-module projects together. The build pom is not the parent pom, each separate multi-module project has its own parent pom.
In the build pom, I set up the nexus staging plugin:
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.3</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
What happens when I build, is that all the sub-modules are built and uploaded to nexus in a staging repo (say #4005). Then at the end the above plugin opens a new repository (say #4006), uploads just the build pom to it, then closes it. This means that my build pom gets released, but not any of the sub-modules.
Is there some way to explicitly control the life-cycle of this plugin? I want to open new repository at the start of the build, upload all sub modules to it, then close and release it.
If you build pom is NOT a parent, then the different multi-module projects do NOT have a configuration of the staging plugin either. So are they just being deployed via the deploy plugin? That would be a mixed use case that does not work.
You would have to configure your Maven projects so they all run in one reactor and all deploy with the staging plugin.
The only other option I can think of is to run the full build of all the multi-module children as a normal deployment into one or multiple staging repositories and then subsequently release them together with the remote control goals of the staging plugin. That would probably require some scripting or at least some testing how the order of everything works out.

Resources