how to make `mvn package` aware that it has already built the target - maven

In a makefile, I can easily do something like
${target}: ${sources}
mvn package
Where I have ${target} the generated jar file, and ${sources} all the java files and the pom.xml. With this makefile, the target will not be be rebuilt unless one of the sources is changed since the last build of the target. The result is
$> make target/demo-0.8.0-SNAPSHOT-jar-with-dependencies.jar
make: 'target/demo-0.8.0-SNAPSHOT-jar-with-dependencies.jar' is up to date.
But just mvn package will always run the maven-assembly-plugin even though none of the source files has changed.
Question:
Is there a way to make mvn package be aware of the source files, similar to how make knows this so it'll just say "no need, it's already built."

Whether or not something makes sense is maybe up to the use case and the developer.
In a system where integration is far more complicated than passing unit tests the only way to gain confidence is by deploying into a test Kubernetes environment.
Anyway thanks for answering my question that the maven packaging plugin is unable to handle this dependency tracking.

Related

Make maven output show progressed sub-modules only

I am working with an automatic build script in maven 3.x. The parent project contains of more than 60 modules. The compilation is done in a shell script simplified this way:
for each module:
cd module
mvn clean install > compile.$module.log
echo "Compiled $module"
I like to see a list of compiled modules in order to see the progress or the build. I like to have a big maven command and avoid the manual for loop. I hope to speed up the build this way, since splitting the parent project into more independent modules is not a short time option, yet.
The --quiet flag might be enough already. Alternatively a user defined logging implementation would be fine as well, as described in the manual (https://maven.apache.org/maven-logging.html)
The questions are:
What is the prefered way to modify maven log output?
Does anyone already know a ready-to-use plugin for my purpose?
Thanks

Maven test scope dependency change does not recompile module's tests

We have a maven multi-module project in which the following weirdness occurred:
module-x has a TEST (src/test/java/...) which depends on code provided by module-y, whose code is not otherwise used in module-x (i.e. nothing in src/main/java/... depends on module-y)
module-x therefore defines a dependency on module-y, but with <scope>test</scope> and uses that code in one of its tests
someone changed a constructor in module-y and committed the code that broke the module-x test (as it was using the old constructor parameters)
TeamCity ran java org.codehaus.plexus.classworlds.launcher.Launcher -f app-parent/pom.xml -B integration-test when it saw the commit
the build succeeded because maven did NOT recompile/rerun module-x TEST code, it just recompiled module-y and everything that depends on it with default compile scope
I'm sure people will point out, why is that test even in module-x, etc, but this weird setup aside for a minute. What I want to understand is this:
If some project (module-x) has a test dependency (module-y) that changes and is recompiled, should not maven then notice this and do a fresh "test-compile" for the project (module-x) that "test-depends" on what changed (module-y)? Is what I saw here normal behavior?
EDIT: from comment replies it seems like the fact that TeamCity is being used may be a factor; I clarified the command used in the sequence list above.
EDIT 2: I should note that the parameter "-f app-parent/pom.xml" is actually the main module that basically depends on "the world" and is where one would run from command-line "mvn test" or "mvn clean package" to rebuild everything.

Maven - Remove Generated Folders

I'm using the maven-compiler plugin to generate my .jar
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
When I do a clean install it will generate folders such as "generated-sources", "maven-archiver", "maven-status" amd "classes" in addition to my .jar
How could I automatically deleted those folders after the install or prevent them from being generated?
You cannot prevent those folders from being generated as they are essential to making the build work. generated-sources most likely contains Java source code that was generated during the build and is needed to make the rest of the code compile; classes contains the compiled Java source code that was under src/main/java and is needed to make a subsequent JAR or WAR, etc. So, without those folders, the build cannot properly work.
However, they are inherently temporary. In fact, the whole target folder is temporary. It contains data that is generated / copied at build-time and is needed to make the final artifacts. This is why it is generally a good idea to always clean before building a Maven project: it makes sure that this build folder is cleaned so that new fresh data is created (otherwise, it might rely on old build data, potentially making hard to track down bugs).
Once the final artifacts are created, they will be the only one to be considered when installing or deploying the project. If you really want to get rid of those files after the build (but I don't see why), you could always run mvn clean install clean. This will delete the target folder once the project's artifacts are installed.

maven, package without recompile a module

I have a war module (C) that depends on two other modules (A,B). When I change A and do repackaging for C mvn package then B got recompiled as well (although nothing in it changes), and takes a lot of time. How do I tell maven to skip that?
Tks.
Use the new compiler plugin version 3.1. It conducts an incremental compile which works marvellously for me. It does a complete compile when it finds changes in a module, else it does not compile anything.
http://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html
Incremental mode is the default, so in fact there is nothing else to do than updating the version!
Of course you should not perform a clean in advance. This would lead to a full compile always.
Remove B from the project by excluding it from the relevant parent POM. You could do so in a development profile. This way, it is loaded from the maven cache rather than recompiled every time.
You can also use the option -pl. Pl stands for "project list". You type
mvn -pl myProjA,myProjB clean install
This would build only those two projects. But beware, you might oversee necessary projects to build.
http://java.dzone.com/articles/5-maven-tips
I was not able to find this on the maven docs, but I'm sure it's there, too.

Debugging Makefile for target that is not being built

I need some help debugging a Makefile system. I have a rather huge Makefile dependency tree, actually the Android source makefile system.
At some point the build fails because a file is missing:
/bin/bash: out/host/linux-x86/bin/mkfs.ubifs: No such file or directory
The file mkfs.ubifs is supposed to be "build" during the make process, and indeed it works if I do:
make out/host/linux-x86/bin/mkfs.ubifs
The mkfs.ubifs is build, and everything is working, until I again clean everything and build from the beginning.
This indicates to me, that there is a missing dependency somewhere. So my question is, how do I go about debugging this? How do I discover exactly which target is missing a dependency? What options can I provide for make which will give me clues as to where the error is?
Any other suggestions will also be appreciated. Thanks. :)
Update
Using make -d provides quite a lot of output. How exactly do I determine from which make target (sourcefile and line) and error occurred?
Problem solved. It seems make -p was the most useful way to debug this problem:
-p, --print-data-base
Print the data base (rules and variable values) that results from
reading the makefiles; then execute as usual or as otherwise spec-
ified. This also prints the version information given by the -v
switch (see below). To print the data base without trying to
remake any files, use make -p -f/dev/null.
From that output it is relatively easy to determine which target was failing, and what dependency that should be included.
There is a discrepancy between target's prerequisites and its commands, that is, a dependency is not specified for a target. I don't think you can debug that using make means because make can't tell you that a dependency is missing.
However, you can try invoking make with -d switch. That is going to tell you which target it tries to build when it hits the missing file. The next step would be to find the rule for that target in the makefile and add the missing dependency.

Resources