How to structure Maven3 project to produce inputs to generate-sources in another project? - maven-2

I need to generate a few small text files that will be used as inputs during generate-sources phase of another project (data files input to FMPP/FreeMarker). The generator is Java source code - that is, the code that generates the text files is compiled in the first project. In this kind of scenario, how are the data files normally conveyed from one project to the other?
I could cobble together a dozen lame ways to do this - I'm looking for best practice.
At the moment, I'm avoiding the problem by having the first project just produce an executable jar, which is run by the second project to produce the data files. But there's really no reason for the code to be "public" - to be installed - the output of the first project really should just be the TDD files.

I'm not sure I have the full picture of what you're trying to do here but it sounds to me like you should be using the maven dependency plugin.
I'm assuming that the first project would create an artifact with the data files you need for the second and other projects. The second project could use the dependency plugin to unpack that artifact into target/generated-sources or wherever it is needed as part of its build.
For example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>unpack-interfaces</id>
<phase>initialize</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>first-project-artifact</includeArtifactIds>
<includes>*.TDD</includes>
</configuration>
</execution>
</executions>
</plugin>

I hope I don't misunderstand you. You can run a maven2 project with exec-maven-plugin. This will run the first project and produces input for the next. If you should copy the *.tdd files, maybe you can use maven-resources-plugin for this. Hope it helps.

Related

How to include a maven launch config in a maven archetype?

I got a liferay-portlet-project with a sample application/portlet that I want to become an archetype. Inside the project there is a folder containing two *.launch files to redeploy the webapp. Both have the following line which I have trouble with:
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/rawportlet}"/>
where "rawportlet" is the project's name. If I change it manually to ${artifactId} this variable is not resolved when using the archetype to create a project. Resolving this variable during project-generation would be nice.
Is there a way to achieve this? Or a workaround? Thanks in advance for your help.
Workaround: write a maven goal that the user can run after using the archetype. So the steps would be (for example):
generate project from archetype
mvn archetype:generate -DarchetypeCatalog=local
do some post-generation cleanup (execute in project's base dir)
mvn antrun:run
So my code for this is in "pom.xml" in the archetype:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<replace token= "rawportlet" value="${artifactId}" dir="runConfigs">
<include name="**/*.launch"/>
</replace>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
The "runConfigs" directory is where the *.launch files are stored.
Credits to:
Full search and replace of strings in source files when copying resources
Maven, configure specific goal
I have this same problem, and I used a different solution that works okay (but isn't perfect either).
Use value="${workspace_loc}/${artifactId}" in your launch config.
This will work as long as people do an archetype:gen at the workspace root. This works better for me than the selected answer because running that post processing requires another launch configuration (which somewhat defeats the whole purpose).

Execution point between prepare-package and package in Maven build-process

The package phase of a project with packaging war, prepares an exploded-war in the target folder and packages this into the final war-file.
Is it possible to make some changes, editing files, removing files and so on, between prepare-package and package phases? I'm searching for an extension point (Maven execution-phase) where the resources are already copied and in the exploded-war structure.
[maven phase] Copy resources and explode to target/{finalName}.
[custom] Do some complex custom changes (e.g. implemented with maven-antrun).
[maven phase] Package the changed stuff into the final war.
I thought this could be possible between the phases prepare-package and package. Unfortunately after the prepare-package no exploded war is available to be changed and packaged later.
Can you give me a hint how to achieve this? Thank you very much.
This configuration calls the exploded goal in the prepare-package phase. This gives you the chance to work on the exploded war directory in subsequent plugin definitions e.g. maven-antrun.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<id>prepare-war</id>
<phase>prepare-package</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
It sound to me like you should bind the antrun task to the prepare package phase, because at this point the resources have already been processed see Lifecycle Reference.

Aggregate Dependencies in a Multi-Module Maven Project

I am trying to figure out how to aggregate my maven dependencies in a multi-module project. For example, if I have:
root pom/project1
root pom/project2
and I run mvn dependency:copy-dependencies, I end up with the dependencies in:
root pom/project1/target/dependency
root pom/project2/target/dependency
What I really want is that if I run the mvn command in the root pom folder, all of the dependencies to be copied to root pom/dependency. Is there a maven property that gets me the output directory of the root pom? (similar to ${project.build.directory})? I realize that I can just copy all the dependency folders to the same place after the fact, but I was hoping for something a little cleaner.
You will have to configure the dependency plugin to copy depdendencies to a particular location. This can be done by the outputDirectory configuration property.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${outputDir}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
But if you trying to do this for distribution, I'd recommend you create an assembly using the maven assembly plugin
The documentation says:
The Assembly Plugin for Maven 2.0 is primarily intended to allow users to aggregate the
project output along with its dependencies, modules, site documentation, and other files
into a single distributable archive.
What I really want is that if I run the mvn command in the root pom folder, all of the dependencies to be copied to root pom/dependency. Is there a maven property that gets me the output directory of the root pom? (similar to ${project.build.directory})?
No, because modules shouldn't actually be aware of that.
I realize that I can just copy all the dependency folders to the same place after the fact, but I was hoping for something a little cleaner.
The Maven way would to use the Maven Assembly Plugin and a custom descriptor. But if you're not familiar with the Maven Assembly Plugin and its descriptor format, it won't be easy.
A less clean but easier approach would be to configure the Maven Dependency plugin to copy the dependencies into the parent project using a relative path. Something like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<configuration>
<outputDirectory>../root_pom/target/dependency</outputDirectory>
</configuration>
</plugin>
But as I said, this introduces tight coupling between modules and the root project which is not good at all (and I wouldn't go further by including the goal invocation as part of the build, modules should remain independent and you should be able to build one module without "checkouting" the parent).

Simple Mavenization of existing Ant build files

If you have an existing ant file, what is the best way to convert the project to Maven. I've checked out things like fAnt, but if I'm going to mess with this stuff, I might as well go full-bore for Maven. I expected something to exist that can just start the pom.xml for me based on the existing build.xml, but I haven't found anything yet. Suggestions?
I don't know any good automated way to do such a migration because things may just be too different so I would do it manually, step by step, and keep the existing ant build in parallel of the future new one until the whole migration is done (from both technical and human points of view).
First, refactor the existing Ant build to align it on Maven conventions:
Make things modular: if your existing build is a big monolithic build producing several artifacts from a single source tree, break it down into separate modules, one for each artifact.
Update directory structure: Maven comes with a standard directory layout and, while it is possible to customize this layout (i.e. to configure plugins for another layout), this is not really recommended and is more a source of troubles than benefits. So I'd move existing app sources, configuration files, tests, etc to match Maven's layout (e.g. src/main/java for application sources, etc).
Then, start to create the Maven build:
Create POMs for each module: Create a POM, declare external libraries as Maven dependencies (maybe add them to a corporate repository, using an enterprise repository is a good practice in an enterprise context anyway), add dependencies between modules.
Finalize the multi-modules build: Add parent(s) POM(s) and inheritance/aggregating relationships. Test that there is no regression with the created artifacts.
You could do this work in a separate VCS branch if you don't want to change anything until the work is done and create scripts to move things. And when ready, merge the Maven specific stuff and apply the scripts.
You could run the Ant script from Maven with the maven-antrun-plugin. Your pom.xml would look something like this:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>${ant-nodeps.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>init</id>
<phase>compile</phase>
<configuration>
<tasks>
<!-- Ant code goes here -->
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</build>
</project>
That way you can start to move your dependencies into Maven, and reference them in the Ant script like so
${com.foo.bar:my-lib:jar}
Then just start slowly moving pieces of your Ant into pure Maven stuff.

How to remove generated build artifacts from Maven's target directory?

How to remove generated build artifacts from Maven's target directory? Maven generates a jar or war file to target directory. I'd like to remove that file after maven has installed the jar/war file to local repository (that is, after maven has executed the 'install' goal). The remove could happen either at install goal or separate goal I execute manually.
Note, that I'd like leave other parts of target directory intact, for example target/site and target/surefire-reports.
Just use the clean plugin and run an execution after the install phase:
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>auto-clean</id>
<phase>install</phase>
<goals>
<goal>clean</goal>
</goals>
<configuration>
<filesets>
<fileset>
<directory>${project.build.outputDirectory}</directory>
<includes>
<include>**/*.jar</include>
</includes>
</fileset>
</filesets>
</configuration>
</execution>
</executions>
</plugin>
There is nothing built into Maven that can do this. You could use the antrun plugin to execute an Ant script after install that deletes the artifact, or use the exec plugin to use the command line to delete the artifact, or write your own plug-in.
I suggest there is little value, if any, in doing any of these things. Maven is designed to place intermediate and final artifacts in target to make follow-on builds more efficient. The reason that there is nothing available to do this already is an indicator that this is of little value. If it is of value to you, you have a few options.
I know I am a little bit late. But I guess the issue was, that a maven project archives the artifacts automatically. In my case, I disabled the automatic archiving and just archived the artifacts manually using the post build actions. This way, only the artifacts that I am interested in are archived. I am willing to leave the generated artifacts on disk until the next build runs.