This is probably a question on Maven internals, and I haven't had much luck searching and finding the answer. Concisely, I'm interested in seeing what commands Maven actually execute for each phase or goal. For example, mvn package creates the jar file, so I'd think it must call the jar -cf command at some point.
Maven is opinionated so by design, this command doesn't show up in the .pom file. But which commands does Maven actually run for a specific phase and goal? Is there a way to see them?
The call creating a jar file is done in the maven-jar-plugin which is bound to the life cycle. You can do a mvn -X clean package to what happens behind the scenes. But you won't see many commands (except for javac compiling)... What do you mean by: Maven is opinionated so by design, this command doesn't show up in the .pom file?
The life cycles shows what kind of phases run bindings shows which plugins runs in which phase.
If you want to take a look into the sources of plugins all plugins can be found here: https://maven.apache.org/plugins/
On the right side you can see links to the appropriate version control system with links to it.
Each plugin has a link to the source code for example maven-jar-plugin: https://maven.apache.org/plugins/maven-jar-plugin/source-repository.html
Run mvn with the -X parameter, then look for lines starting with "[DEBUG] Executing command line:".
All the plugins are written in Java (or JVM-based languages), so if you can read it - you can find out what it does. Here are for example sources of the maven-jar-plugin: link1, link2.
But to get there you need to figure out which plugins and goals are executed when you run a phase. There are multiple ways:
In the output Maven says which goals it executes, example:
maven-resources-plugin:2.6:resources (default-resources) # module-name
If you generate an Effective POM, you'll be able to see all the plugins and which phases they are bound to: mvn help:effective-pom. Some plugins have default phases so people don't have to specify them explicitly - for these you'd have to look into the plugin meta information or into the sources.
Default plugins and goals are defined by the packaging. For the default packagings you could look into default-bindings.xml (role-hint is the packaging name).
After you know which plugins and goals are executed you can check out the sources of each plugin (the sources are usually open) and see its Mojos for the actual source code.
If you decide to learn the code it would be useful to be able to debug it when you run a mvn command. For that you can use mvnDebug instead of mvn.
More info: click1, click2.
Related
I wrote a Mojo that creates a new Java class and puts it in /target/generated-sources/annotations. in addition, I have configured build-helper-maven-plugin to declare that folder as source folder.
The problem is when I do: mvn clean install from CLI it generates the source file but it doesn't compile it.
Note, if I run Maven Install from within Eclipse (using the m2e connector) then it works fine.
What am I missing?
Without an actual plugin definition, we can only speculate.
I can't comment on m2e, I see one obvious difference that you state by yourself: mvn clean install vs mvn install, but from the "bare" maven's standpoint,
here is one possible reason:
Maven has a concept of phases that comprise the lifecycle. An information about phases of default lifecycle is available here
Plugins (more precisely the "goals" of plugins) are something that usually gets attached to a particular phase.
Maven compiler plugin is attached to the compile phase, for example.
So, maybe the plugin that you've developed runs later than the compiler plugin.
Usually, source generation plugins are attached to generate-resources phase.
Its possible to run a full lifecycle in maven, in fact its what people usually do, for example, running mvn test actually means, run all phases of the default lifecycle up-to (including) phase test.
It's also possible however to run a particular plugin goal "directly" without attaching it to the phase. Of course, in this case, its pre-conditions should be met.
For example, mvn surefire:test means that we should invoke the surefire plugin directly. Of course the source code and test code should be compiled beforehand (bytecode has to exist in the target directory)
So I suggest you to run the following series of commands (Adjust if you have tests):
Run mvn clean install on the plugin project to place it to local m2 repo
Run the plugin directly: mvn ::: and check
whether the source is generated in the target folder
Make sure in pom.xml of the project that the source folder are configured correctly
Run mvn compile (phase up-to, including, compile) on pom even without the plugin
After this phase, there will be compiled sources in the target directory. Don't run
clean because it will wipe out all the target directory
This will effectively help to make sure that plugin does the job right
I am learning about Jenkins and I have to explore some existing build jobs that others wrote (in the company that I'm working).
So I am trying to understand a job which uses mvn command.
So under the build part (inside the job), I see these details:
Maven version: 3.0.5
Root POM: pom:xml
Goals and options: clean install -U -Pnotest,docs
I'm trying to understand what this mvn command means?
I tried to google it: "clean install -U"
But I didn't find what the parameter U means.
And I don't know what is "-Pnotest,docs".
can you guide me regarding how I can find what's it? (maybe "-Pnotest,docs" is from a xml file or it's from the artifactory etc..)
Thanks a lot!!!!
-U Forces a check for miss releases and updated snapshots on remote repositories
If Maven is regularly used in your company, and you will have to work with it on a day-to-day basis, I would advise you to find a mentor (any colleague that knows the tool well and is ready to share its knowledge with you) and work with them. Maven, when you first look at it, can be quite of a mouthful and you'll learn it more efficiently with their help.
For the problem at hand, Elarbi Mohamed Aymen's answer already tells you what the -U flag corresponds to. As for -P, it is used to activate profiles (in your case notest and docs). These profiles are usually defined in the pom.xml of the project being build.
See Running Apache Maven for the basic commands, and as advised on that page run mvn -h to have the complete list of flags the command can use.
Maven is one of the mechanism how to handle the build process and check project dependencies, especially for Java.
One of the option can be to have physically included dependencies (artifacts / libs) in the project, but its not so useful- in case of new version, you have to replace the file, sometimes you are using same lib in more apps, ten you have to handle it manually in all projects.
Except this, there is the maven- it has a global repository with shared artifacts / libs , which are common used- ref. https://repo1.maven.org/maven2/.
Except this, you can make your own libs/ artifacts in this case, its a modules / applications which are reusable, then you are storing it in private repository- this is the artifactory.
When you want to build your project, in case of maven project you have pom.xml , which is like manual for maven what to do / how to build.
clean and install are common goals, clean will wipe your local maven repository, install will download them again, with parameter -U it force to download them.
You can define your own goals in pom file, eg. to "tree build"- build some dependent modules, then build parent project.
Eg. with -D you pass parameters to the maven eg.
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app
- that will generate new project, based on given archetype- "template", with the given groupID and artifactID- groupID can be eg. company name, artifactID is then the name of specific app / component.
-P,--activate-profiles <arg> Comma-delimited list of profiles
to activate
-D,--define <arg> Define a system property
I'm trying to run 'mvn clean install' in a sub-module of a multi-module project. The project is Jacoco but I assume it's more an issue of me not understanding how Maven is being used here than an issue with Jacoco itself.
https://github.com/jacoco/jacoco/blob/master/jacoco-maven-plugin.test/it/it-site/pom.xml
I get the following error:
[ERROR] Plugin #project.groupId#:jacoco-maven-plugin:#project.version#
or one of its dependencies could not be resolved: Failed to read
artifact descriptor for
#project.groupId#:jacoco-maven-plugin:jar:#project.version#
I see the following in the pom:
<groupId>#project.groupId#</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
I'm not familiar with using the # symbol in #project.groupId# although i assume it is somehow supposed to get substituted at runtime.
I can run Maven from the top level pom and I even see [INFO] Building: it-site/pom.xml in the log but a target directory is not created there.
A nudge in the right direction would be appreciated.
This probably has something to do with the pom file here: https://github.com/jacoco/jacoco/blob/master/jacoco-maven-plugin.test/pom.xml
It is using a plugin called the maven invoker.
The Invoker Plugin is used to run a set of Maven projects. The plugin can determine whether each project execution is successful, and optionally can verify the output generated from a given project execution.
And if you read about filtering files with this plugin, it mentions:
POM files selected by the include/exclude patterns. The tokens to be filtered must be enclosed in #...# to avoid interferences with Maven's normal POM interpolation, i.e. use #project.version# instead of ${project.version}.
Regarding why the Invoker Plugin and filtering is being used here...
The Spring Boot documentation provides some relevant background on why that is. Although the docs are for Spring Boot, i think it applies to testing all plugins (which Jacoco is).
Multi-module Maven builds cannot directly include maven plugins that
are part of the reactor unless they have previously been built. ...
The standard build works around this restriction by launching the
samples via the maven-invoker-plugin so that they are not part of the
reactor.
The sample application are used as integration tests during the build
(when you mvn install). Due to the fact that they make use of the
spring-boot-maven-plugin they cannot be called directly, and so
instead are launched via the maven-invoker-plugin.
I'm looking for a way, to execute additional commands (e.g. a perl script) after running mvn archetype:generate on my custom archetype automatically.
Is this possible?
Context
I'm writing an archetype, that creates OSGi bundles which i want to integrate into a parent project as modules. After generating the bundle, i wish to organise it into the parents directory structure and then manipulate poms and other configuration files automatically.
This has been asked on maven forums before 1, however no answer was given.
Thrau, you can invoke mojo post execution of archetype:generate by adding -Dgoals="your custom mojo plugin", within the plugin you can write your custom code. Hope this helps.
Yay, my thesis is done! Now that the pressure is off and I've had my fill of playing Skyrim, I'm converting the code I wrote for my thesis from a chaotic directory built with ant to a nice maven project.
I originally had a bin directory with about 20 bash scripts that ran the various java and ruby programs used in my thesis, including the final jruby/sinatra-based web server. I am planning on moving my scripts to src/main/scripts, but I need to figure out how to handle the classpath.
I had previously just hardcoded paths in my scripts to the manually-downloaded dependencies. However, now that maven is downloading and storing all the jars I need, what's the best way to reference them from my scripts:
Should I just get the scripts to reference the full paths of various jars in the local repository like before?
Should I make the local repository directory a configuration option for my scripts and use relative paths to this directory?
Should I build a big hairy jar with all the dependencies using the maven assembly plugin and access this via the script-relative path ../../../target/*-jar-with-dependencies.jar?
Is there some better option I haven't thought of?
In your script, use the exec:java plugin to run Java classes. It will sort out the classpath based on the defined dependencies. Then you don't need to worry about it.
Relook at all the scripts that you have. Potentially you could achieve the functionality of some of them using maven exec plugin.
Besides assembly and shade plugins, you may want to look at the functionalities provided by maven dependency plugin as well.
In my project (Soluvas fb-tools/fbcli), because I use Java 6 and later (which supports wildcard classpaths), here's what I do:
#!/bin/bash
# Must run first: mvn package dependency:copy-dependencies
java -cp 'target/dependency/*:target/fbcli-1.0.0-SNAPSHOT.jar' org.jboss.weld.environment.se.StartMain "$#"
No need for manual generation of classpaths. :)
There are quite some plugin doing similar things you mentioned. Assembly plugin you mentioned is doubtless one of them (and the way you suggested is also a neat working solution).
You may want to take a look in AppAssembler and Shade. They all provide some mechanism to bundle the dependencies and produce a directly executable package.
Here is CLI example using Maven plugin exec:java as mentionned by #artbristol in another comment:
mvn exec:java -Dexec.mainClass="mypackage.MyClassWithMain" -Dexec.args="arg1 arg2"