So we have 6 child pom modules with 4 of them sharing common elements for build with few differences that would be parameterized.
So can we have a util pom move these common things and resue across.
I do not want to move to parent, since it is not for all the child modules.
Please suggest if there is a way for this or alternatives. Thanks
Not possible.
You cannot import parts of POMs. This would be desirable in some cases (I know that) but we probably need to wait for Maven 5.0.0 for that.
What I would recommend:
Define all your plugins and executions in the parent POM.
Use or define properties to skip them if necessary.
Override the properties in the modules.
This means
If your plugin corresponds to property myplugin.skip that skips the execution, set this to true in the parent POM and set it to false in all modules that need it.
If your plugin has a configuration parameter skip, but no property, add something like <skip>${myplugin.skip}</skip> to the configuration and then use the property myplugin.skip.
Do the same if you have more than one execution of a plugin and you need separate skip parameters.
If a plugin does not have skip parameter at all (luckily, most plugins have one), you can help yourself by using <phase>${myplugin.phase}</phase> and either put none or the correct phase in there.
Related
What is the best way to find the right dependency for a used class that are part of the maven-online-repository?
As far I see it is this approach:
lookup the import (e.g. org.whatever.X;) from your code at the maven-repository online (search.maven.org).
Pick one of the result list and include it in the dependency section of the POM.
Hope the chosen version and artifact of the dependency matches your requirements (compiling, runtime). If not try another artifact or version.
I'd like to share my way of doing it. What do you mean by "finding the ... for a used class that are part of the ..."? Do you mean that the dependancy is already used in somewhere else, or that you only know the package name that you may need?
I would first check which version I need for the current project.
If I'm working on a team project and someone has used the dependency in somewhere else, I would check their pom (to ensure we are using the same dependency).
Then I would look up the dependency in Maven repo and include it in my pom.
Hope this helps.
Essentially, yes this is what you have to do to obtain libraries/modules for your project.
Something that's helped me out though with this specific problem: versioning. You can set the versions you need for each of your dependencies with <properties> -> <gson.version>2.8.1</gson.version> (for example). That way, you can guarantee that your build matches with the reqs of the class or type of code you're trying to implement.
Maven doc ref: https://maven.apache.org/pom.html#Properties
I'm the author of one of the Maven plugins (not Apache/Codehaus, completely indie). Sometimes I get support requests or test cases where I'd really need to debug the execution of my plugin with an existing pom.xml. Basically the test cases I get are sample/test project (pom.xml with src/main/resoures, src/main/java and so on).
What I need is a way to:
Load an existing pom.xml.
Find a specific execution of my plugin there (usually it's the only one).
Get an instance of MyMojo - fully initialized/condigured, with all the components and parameters corectly injected.
Execute MyMojo.
What's important is that test projects are separate projects, I don't want to copy them into the Maven module of my plugin.
I'd like to be able to do this without remote debugging.
By debugging I mean to be able to set and halt on breakpoints (also conditional), step in/out/over on the source code.
Ideally I'd like to be able to executeMyMojoFrom(new File("pom.xml")) - for instance in a JUnit test or a main method of some class. (I can supply groupId, artifactId etc. All other definitions should just be loaded from that pom.xml.)
How can I achieve this?
What I've tried so far:
Debug As... on pom.xml in Eclipse - does not work well enough (source code not found, breakpoint don't work as its not a Java project context)
Maven Embedder/Invoker solutions - spawn things in separate processes via CLI. Forget breakpoints, no debugging.
Remote debugging with mvnDebug and then remote debugging from Eclipse as suggested by Pascal Thivent here. This is so far the best option. However, remote debugging means starting mvnDebug separately, and there's also not guarantee that the JARs I have in Eclipse are exactly the same that mvnDebug is using. So there's a certain distance here.
maven-plugin-testing-harness - I actually thought this this will do the task. But first I was jumping through hoops for a few hours just to make it start. All of the important dependencies are "provided" so I first had to figure out the right combination of versions of these artifacts. And then - only to discover that AbstractMojoTestCase only works within the plugin module you want to test. Probably I was mistaken when I thought that maven-plugin-testing-harness was a testing harness for Maven plugins. It seems that it's a testing harness for the plugin from that plugin's module. Which is not illogical but does not help my case. I'd like to test my plugin in other modules.
So right now I've got the best results with the remote debugging solution. But what I'm looking for is really something like maven-plugin-testing-harness but not hardwired to the plugin module. Does anyone happen to have a hint, if such a method exists somewhere in Maven artifacts?
To be even more specific, I'd like to write something like:
public void testSomething()
throws Exception
{
File pom = getTestFile( "pom.xml" );
assertNotNull( pom );
assertTrue( pom.exists() );
MyMojo myMojo = (MyMojo) lookupMojo( "myGroupId", "myArtifactid", ...,
"myGoal", pom );
assertNotNull( myMojo );
myMojo.execute();
...
}
Compare it to the MyMojoTest here - it's almost there. Should just not be hardwired into the mymojo Maven module (as it is in maven-plugin-testing-harness).
Update
Few answers to the questions in comments:
You mean you don't want such a test class, i.e MyMojoTest to reside inside the same project as the MyMojo, i.e your plugin project? Why is that?
Exactly. I want to debug the plugin execution in an existing Maven project, I don't want to move that project to my plugin project first to be able to run a test. I want to be able to test/debug an existing project. Ideally, I'd just need to add my-maven-plugin-testing dependency and subclass MyMojoTest in the project's src/test/jaca. This would be a good instrument to debug executions. Dragging the target project into my Mojo project ist just too much overhead - and mostly these aren't really the test cases I want to keep long-term. I hope, this answers, why.
Anyway, it's merely a convention to keep the project-to-test/pom.xml inside the src/test/resources of your plugin module, not a rule...
My problem is not the location of the pom.xml of the project-to-test, that is easily configurable. My difficulty is that maven-plugin-testing-harness is is somehow hardcoded to be in the Mojo's project. It uses the pom.xml of the Mojo, looks for other special files/descriptors in the containing project. So I somehow can't use it in a non-Mojo project, or can I? This is my question.
And I'm not sure why Debug as... didn't help you...
Not sure either, but (1) breakpoints did not work and (2) the source code was not "attached" for some reason.
If the Debug as didn't work for you as well as it should, you can try to use the mojo-executor with a bit of work.
https://github.com/TimMoore/mojo-executor
This is how you would execute the copy-dependencies goal of the Maven Dependency Plugin programmatically:
executeMojo(
plugin(
groupId("org.apache.maven.plugins"),
artifactId("maven-dependency-plugin"),
version("2.0")
),
goal("copy-dependencies"),
configuration(
element(name("outputDirectory"), "${project.build.directory}/foo")
),
executionEnvironment(
mavenProject,
mavenSession,
pluginManager
)
);
The project, session, and pluginManager variables should be injected via the normal Mojo injection. Yes, that means this should be executed from the context of another maven plugin. Now that I think about it, whether this would help you in any way is still a question because this still relies on injection of such components by the underlying plexus container.
My original idea was though to have you build a maven plugin that would invoke your jaxb2 plugin thru the mojo-executor like above, then serialize the mavenProject, mavenSession, pluginManager, i.e, all the plexus injected components and then use those objects to invoke your jaxb2 plugin in future from a standalone class without the plugin that you built.
Is it possible to define an extra property in project A and have it visible in project B? The root projects obviously includes both.
I tried putting this in project A's build.gradle:
ext {
myProps = 'something to say'
}
And this in project B's build.gradle:
task('X', dependsOn: [':A:someTask']){
println(project('A').myProps)
}
but I get:
FAILURE: Build failed with an exception.
...
* What went wrong:
A problem occurred evaluating project ':B'.
> Could not find property 'myProps' on project ':A'.
How can I achieve this?
An extra property is accessible from anywhere the owning object (A's Project object in this case) is accessible from. However, it isn't considered good style to reach out into the project model of a sibling project. One reason is that this can make it necessary to tweak the configuration order of projects, but there are others. Instead, it's better to either declare the extra property in a common parent project, or in a script plugin that gets applied to all projects that need to access the extra property.
PS: In the same vein, an explicit cross-project task dependency should be avoided whenever possible. Also note that your task tries to print the extra property in the configuration phase (rather than the execution phase), which may or may not be what you want.
I want to create an Archetype in which the user can provide artifactId. Then I want to take this artifactId and create two files.
Here is an example.
artifactId= box
FILE 1: copy-box.txt
FILE 2 : Box.java
Creating copy-box.txt is quite easy. But how to create Box.java with B capital?
I looked through the code that creates the replacement in the filenames of the archetype resources (which can be found here). It seems that the values of the arguments are taken from the context, which means that they are not evaluated. In my opinion, for the moment it is not possible (sad, but true) to use the evaluation mechanism directly in the file names.
However, by simply implementing the FilesetArchetypeGenerator interface, a good contribution can be made to the archetypes generation.
There is a bug in maven archetype. See bug reports ARCHETYPE-406 and ARCHETYPE-397.
When fixed it will be possible to define and use custom requiredProperty for your case.
In archetype-metadata.xml add
<requiredProperties>
<requiredProperty key="classPrefix" >
<defaultValue>
${artifactId.substring(0,1).toUpperCase()}${artifactId.substring(1)}
</defaultValue>
</requiredProperty>
</requiredProperties>
Don't forget to add classPrefix to archetype.properties
I've just fought for a whole day with a strange maven problem:
I had a custom property called "deployment.name" that was never to resolved to what I configured for it, but rather the maven filtering mechanism always replaced it by the project's name.
I tried the goal "help:expressions" to find out whether this is a preconfigured property, but that goal only throws exceptions in m2eclipse. Google does not seem to know a pre-configured
property by that name.
The strangest bit: deployment.somethingelse works perfectly fine, so I ended up replacing ".name" with ".depname", then it works ;.)
The Maven Super POM defines the common configuration for all Maven projects. The values in that are accessible as properties (and , so that is where most of the properties you generally use come from (e.g. ${project.build.directory}), these are the pretty much the same as the output of help:expressions.
There is no deployment section in the super POM. The only thing I can think of is that the property is being set somewhere else, e.g. in a profile, or overridden by a plugin (though that seems unlikely). You could try running mvn help:effective-pom to see if the property is being set by a profile.
Are you able to post your POM? that might help diagnose it.
... I just ran help:effective-pom, and there is no trace of "deployment.name" in the output.
I can see all the other properties that I defined though (e.g. "deployment.depname").
Maybe "name" is a reserved attribute of some sort? Maybe debugging into m2eclipse will shed light on this riddle.