You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@maven.apache.org by gevaudan <ca...@gmail.com> on 2012/05/05 21:07:04 UTC
Inject maven dependencies programatically through plug-in
Is there a way to inject dependencies programatically in a maven plugin as if
they were declared in the POM itself? I only found one post discussing this
and it did not help.
Why do I want to do this?
Assume I have a fruit pom which imports a bom-pom which declares version
numbers for fruits, vegetables and other artifacts. Example:
fruit pom:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com</groupId>
<artifactId>foods</artifactId>
<version>10.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupid>com</groupId>
<artifactId>apple</artifactId>
<classifier>fruit</classifier>
</dependency>
<dependency>
<groupid>com</groupId>
<artifactId>orange</artifactId>
<classifier>fruit</classifier>
</dependency>
</dependencies>
food pom:
<dependencies>
<dependency>
<groupid>com</groupId>
<artifactId>apple</artifactId>
<version>1.0-SNAPSHOT</version>
<classifier>fruit</classifier>
</dependency>
<dependency>
<groupid>com</groupId>
<artifactId>orange</artifactId>
<version>2.0-SNAPSHOT</version>
<classifier>fruit</classifier>
</dependency>
<dependency>
<groupid>com</groupId>
<artifactId>artichoke</artifactId>
<version>3.0-SNAPSHOT</version>
<classifier>vegetable</classifier>
</dependency>
<dependency>
<groupid>com</groupId>
<artifactId>asparagus</artifactId>
<version>4.0-SNAPSHOT</version>
<classifier>vegetable</classifier>
</dependency>
</dependencies>
The fruit pom only needs to inject dependencies that have a classifier of
type fruit. The goal is to do this programatically so user's do not have to
edit multiple pom files when adding a new dependency.
The real use case is more complicated than this but I hope the above example
gets at the heart of the question.
I understand I can use the maven model api to read and write poms but that
seems to require an intermediate step and perhaps a second instance of maven
to be spawned in order to consume the intermediate pom. Ideally I would
like to avoid this step and inject dependencies programatically into the pom
which declares the plugin-in itself. Is this even possible or is the pom
immutable?
--
View this message in context: http://maven.40175.n5.nabble.com/Inject-maven-dependencies-programatically-through-plug-in-tp5688342.html
Sent from the Maven - Users mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org
Re: Inject maven dependencies programatically through plug-in
Posted by Jörg Schaible <Jo...@scalaris.com>.
Hi,
I realize now that your use case is somewhat different. The code snippet
below relies on the fact that you have already declares an artifact with
same G:A:V and you like to add an artifact with a different classifier. The
depMgmgt stuff is already resolved at that time. It does *not* cover adding
a dependency with a new G:A:V. As Wayne said in the reply to your other
mail, that would be a bad idea, because Maven reactor could no longer
calculate the correct build order.
- Jörg
Jörg Schaible wrote:
> Hi
>
> gevaudan wrote:
>
>> Is there a way to inject dependencies programatically in a maven plugin
>> as if
>> they were declared in the POM itself? I only found one post discussing
>> this and it did not help.
>>
>> Why do I want to do this?
>>
>> Assume I have a fruit pom which imports a bom-pom which declares version
>> numbers for fruits, vegetables and other artifacts. Example:
>>
>> fruit pom:
>>
>> <dependencyManagement>
>> <dependencies>
>> <dependency>
>> <groupId>com</groupId>
>> <artifactId>foods</artifactId>
>> <version>10.0-SNAPSHOT</version>
>> <type>pom</type>
>> <scope>import</scope>
>> </dependency>
>> </dependencies>
>> </dependencyManagement>
>> <dependencies>
>> <dependency>
>> <groupid>com</groupId>
>> <artifactId>apple</artifactId>
>> <classifier>fruit</classifier>
>> </dependency>
>> <dependency>
>> <groupid>com</groupId>
>> <artifactId>orange</artifactId>
>> <classifier>fruit</classifier>
>> </dependency>
>> </dependencies>
>>
>> food pom:
>>
>> <dependencies>
>> <dependency>
>> <groupid>com</groupId>
>> <artifactId>apple</artifactId>
>> <version>1.0-SNAPSHOT</version>
>> <classifier>fruit</classifier>
>> </dependency>
>> <dependency>
>> <groupid>com</groupId>
>> <artifactId>orange</artifactId>
>> <version>2.0-SNAPSHOT</version>
>> <classifier>fruit</classifier>
>> </dependency>
>> <dependency>
>> <groupid>com</groupId>
>> <artifactId>artichoke</artifactId>
>> <version>3.0-SNAPSHOT</version>
>> <classifier>vegetable</classifier>
>> </dependency>
>> <dependency>
>> <groupid>com</groupId>
>> <artifactId>asparagus</artifactId>
>> <version>4.0-SNAPSHOT</version>
>> <classifier>vegetable</classifier>
>> </dependency>
>> </dependencies>
>>
>> The fruit pom only needs to inject dependencies that have a classifier of
>> type fruit. The goal is to do this programatically so user's do not have
>> to edit multiple pom files when adding a new dependency.
>>
>> The real use case is more complicated than this but I hope the above
>> example gets at the heart of the question.
>>
>> I understand I can use the maven model api to read and write poms but
>> that seems to require an intermediate step and perhaps a second instance
>> of maven
>> to be spawned in order to consume the intermediate pom. Ideally I would
>> like to avoid this step and inject dependencies programatically into the
>> pom
>> which declares the plugin-in itself. Is this even possible or is the pom
>> immutable?
>
> Look at the following code snippet, it should give you the idea:
>
> ================== %< =================
> /**
> * The maven project.
> *
> * @parameter expression="${project}"
> * @required
> * @readonly
> * @description "the maven project to use"
> */
> private MavenProject project;
>
> /**
> * Used to look up Artifacts in the remote repository.
> *
> * @component role="org.apache.maven.artifact.factory.ArtifactFactory"
> * @required
> * @readonly
> */
> protected ArtifactFactory factory;
>
> /**
> * Used to look up Artifacts in the remote repository.
> *
> * @component role="org.apache.maven.artifact.resolver.ArtifactResolver"
> * @required
> * @readonly
> */
> protected ArtifactResolver resolver;
>
> /**
> * Location of the local repository.
> *
> * @parameter expression="${localRepository}"
> * @readonly
> * @required
> */
> protected ArtifactRepository local;
>
> /**
> * List of Remote Repositories used by the resolver
> *
> * @parameter expression="${project.remoteArtifactRepositories}"
> * @readonly
> * @required
> */
> protected List<?> remoteRepos;
>
>
> public void execute() throws MojoExecutionException, MojoFailureException
> {
> List<Artifact> vegetables = new ArrayList<Artifact>();
> @SuppressWarnings("unchecked")
> final Set<Artifact> dependencies = project.getArtifacts();
> if (dependencies != null && !dependencies.isEmpty()) {
> for (final Artifact artifact : dependencies) {
> if (artifact.getClassifier().equals("vegetable") {
> vegetables.add(artifact);
> break;
> }
> }
> }
> if (vegetables.isEmpty()) {
> throw new MojoFailureException("There is no vegetable dependency");
> }
> for(final Artifact vegetable : vegetables) {
> final File vegetable = serviceEjb.getFile();
> final Artifact descriptors =
> factory.createArtifactWithClassifier(
> vegetable.getGroupId(), vegetable.getArtifactId(),
> vegetable.getVersion(), "jar", "fruit");
> descriptors.setScope(Artifact.SCOPE_PROVIDED);
> final String descriptorFileName =
> vegetable.getName().substring(0, vegetable.getName().length()
> - vegetable.getArtifactHandler().getExtension().length() - 1)
> + "-fruit." + descriptors.getArtifactHandler().getExtension();
> final File descriptorsFile = new File(vegetable.getParentFile(),
> descriptorFileName);
> if (descriptorsFile.isFile()) { // file in current build ?
> descriptors.setFile(descriptorsFile);
> descriptors.setResolved(true);
> } else {
> try {
> resolver.resolve(descriptors, remoteRepos, local);
> } catch (final ArtifactResolutionException e) {
> throw new MojoExecutionException("Unable to resolve artifact.",
> e);
> } catch (final ArtifactNotFoundException e) {
> throw new MojoExecutionException("Unable to find artifact.", e);
> }
> }
>
> final File file = descriptors.getFile();
> if (!file.isFile()) {
> throw new MojoFailureException("Fruit is missing: "
> + file.getAbsolutePath());
> }
> // do what you have to do
> }
> }
> ================== %< =================
>
> Hope this helps,
> Jörg
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org
Re: Inject maven dependencies programatically through plug-in
Posted by Jörg Schaible <Jo...@scalaris.com>.
Hi
gevaudan wrote:
> Is there a way to inject dependencies programatically in a maven plugin as
> if
> they were declared in the POM itself? I only found one post discussing
> this and it did not help.
>
> Why do I want to do this?
>
> Assume I have a fruit pom which imports a bom-pom which declares version
> numbers for fruits, vegetables and other artifacts. Example:
>
> fruit pom:
>
> <dependencyManagement>
> <dependencies>
> <dependency>
> <groupId>com</groupId>
> <artifactId>foods</artifactId>
> <version>10.0-SNAPSHOT</version>
> <type>pom</type>
> <scope>import</scope>
> </dependency>
> </dependencies>
> </dependencyManagement>
> <dependencies>
> <dependency>
> <groupid>com</groupId>
> <artifactId>apple</artifactId>
> <classifier>fruit</classifier>
> </dependency>
> <dependency>
> <groupid>com</groupId>
> <artifactId>orange</artifactId>
> <classifier>fruit</classifier>
> </dependency>
> </dependencies>
>
> food pom:
>
> <dependencies>
> <dependency>
> <groupid>com</groupId>
> <artifactId>apple</artifactId>
> <version>1.0-SNAPSHOT</version>
> <classifier>fruit</classifier>
> </dependency>
> <dependency>
> <groupid>com</groupId>
> <artifactId>orange</artifactId>
> <version>2.0-SNAPSHOT</version>
> <classifier>fruit</classifier>
> </dependency>
> <dependency>
> <groupid>com</groupId>
> <artifactId>artichoke</artifactId>
> <version>3.0-SNAPSHOT</version>
> <classifier>vegetable</classifier>
> </dependency>
> <dependency>
> <groupid>com</groupId>
> <artifactId>asparagus</artifactId>
> <version>4.0-SNAPSHOT</version>
> <classifier>vegetable</classifier>
> </dependency>
> </dependencies>
>
> The fruit pom only needs to inject dependencies that have a classifier of
> type fruit. The goal is to do this programatically so user's do not have
> to edit multiple pom files when adding a new dependency.
>
> The real use case is more complicated than this but I hope the above
> example gets at the heart of the question.
>
> I understand I can use the maven model api to read and write poms but that
> seems to require an intermediate step and perhaps a second instance of
> maven
> to be spawned in order to consume the intermediate pom. Ideally I would
> like to avoid this step and inject dependencies programatically into the
> pom
> which declares the plugin-in itself. Is this even possible or is the pom
> immutable?
Look at the following code snippet, it should give you the idea:
================== %< =================
/**
* The maven project.
*
* @parameter expression="${project}"
* @required
* @readonly
* @description "the maven project to use"
*/
private MavenProject project;
/**
* Used to look up Artifacts in the remote repository.
*
* @component role="org.apache.maven.artifact.factory.ArtifactFactory"
* @required
* @readonly
*/
protected ArtifactFactory factory;
/**
* Used to look up Artifacts in the remote repository.
*
* @component role="org.apache.maven.artifact.resolver.ArtifactResolver"
* @required
* @readonly
*/
protected ArtifactResolver resolver;
/**
* Location of the local repository.
*
* @parameter expression="${localRepository}"
* @readonly
* @required
*/
protected ArtifactRepository local;
/**
* List of Remote Repositories used by the resolver
*
* @parameter expression="${project.remoteArtifactRepositories}"
* @readonly
* @required
*/
protected List<?> remoteRepos;
public void execute() throws MojoExecutionException, MojoFailureException
{
List<Artifact> vegetables = new ArrayList<Artifact>();
@SuppressWarnings("unchecked")
final Set<Artifact> dependencies = project.getArtifacts();
if (dependencies != null && !dependencies.isEmpty()) {
for (final Artifact artifact : dependencies) {
if (artifact.getClassifier().equals("vegetable") {
vegetables.add(artifact);
break;
}
}
}
if (vegetables.isEmpty()) {
throw new MojoFailureException("There is no vegetable dependency");
}
for(final Artifact vegetable : vegetables) {
final File vegetable = serviceEjb.getFile();
final Artifact descriptors =
factory.createArtifactWithClassifier(
vegetable.getGroupId(), vegetable.getArtifactId(),
vegetable.getVersion(), "jar", "fruit");
descriptors.setScope(Artifact.SCOPE_PROVIDED);
final String descriptorFileName =
vegetable.getName().substring(0, vegetable.getName().length()
- vegetable.getArtifactHandler().getExtension().length() - 1)
+ "-fruit." + descriptors.getArtifactHandler().getExtension();
final File descriptorsFile = new File(vegetable.getParentFile(),
descriptorFileName);
if (descriptorsFile.isFile()) { // file in current build ?
descriptors.setFile(descriptorsFile);
descriptors.setResolved(true);
} else {
try {
resolver.resolve(descriptors, remoteRepos, local);
} catch (final ArtifactResolutionException e) {
throw new MojoExecutionException("Unable to resolve artifact.", e);
} catch (final ArtifactNotFoundException e) {
throw new MojoExecutionException("Unable to find artifact.", e);
}
}
final File file = descriptors.getFile();
if (!file.isFile()) {
throw new MojoFailureException("Fruit is missing: "
+ file.getAbsolutePath());
}
// do what you have to do
}
}
================== %< =================
Hope this helps,
Jörg
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org