You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@maven.apache.org by "G. Gustavo Pollitzer" <gg...@intelap.com> on 2011/10/28 23:21:18 UTC
scope management without losing granularity
¡Hello! I need to do something that, according to what I know, it is not
supported by maven. Tell me if I am wrong.
Let BoM be a Bill of Materials (a POM with pom packaging type that,
apart of the coordinates, only contains a <dependencyManagement> element
which specifies the version of a bundle of artifacts).
Let A3 be an artifact contained in BoM (its version is specified in the
<dependencyManagement> element of BoM).
Let A2 be third party artifact that depends on A3 with compile scope.
Let A1 be an artifact that depends on A2 also with compile scope.
Let E be POM that imports (or inherits from) BoM and whose
<dependencies> element contains A1.
Suppose it is needed to override the scope of A3 in E. By example,
change it to 'provided' because E packaging type is 'ear' and A3 is
provided by the application server.
According to my knowledge, there is no proper way to override the scope
of A3 without specifying its version nor losing granularity.
If I made use of the <dependencyManagement> element of E to override the
scope of A3, I would be forced to specify an A3's valid version, and
that opposes to the "Bill of Materials" pattern.
If I added A3 as another dependency of E with the desired scope, I would
fall in the error of forcing E to depend on A3, fact that could be true
in the current A2 version but may change in the future.
For the case of the example, the only solution I found is to put A3 as
an excluded transitive dependency this way:
<code>
...
<artifactId>E</artifactId>
...
<dependencies>
...
<dependency>
<groupId>org.test</groupId>
<artifactId>A2</artifactId>
<excludes>
<exclude>
<groupId>org.test</groupId>
<artifactId>A3</groupId>
</exclude>
<excludes>
...
</dependency>
</dependencies>
...
</code>
The drawbacks of this approach are:
- It only solves the case of the mentioned example where the final
objective is to avoid A3 be included in the "E.ear".
- If another artifact, call it X, depended on E with compile scope, it
would (at least) throw compilation error if X tries to define a class
that inherits from a class defined in A3.
- If E has many direct dependencies that transitively depend on A3, the
exclusion would be necessarily and inconveniently repeated in all of them.
If I am not wrong and the above mentioned is not supported by maven, it
occurred to me two improvements to solve it: To permit the
<dependencyManagement> element to contain dependencies whose cordinates
don't specify the version of artifacts that are already managed in a
parent's of imported POM's <dependencyManagement> element; or to add a
new kind of element inside the <dependencies> element to manage scope
overrides. I prefer the second alternative because in the first some
granularity is lost because the <dependencyManagement> element affects
the children also.
I hope I am wrong and you illuminate my brain,
Happily,
Gustavo Pollitzer
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org
Re: scope management without losing granularity
Posted by Ron Wheeler <rw...@artifact-software.com>.
On 31/10/2011 3:39 PM, Gustavo Pollitzer wrote:
> Ron said:
>
>> *If a JAR does not contain all of the dependencies that it needs, a
>> person using that JAR must have some way to know what is missing and what
>> version is required.
>> They will only find out at run-time that this jar depends on a missing
>> dependency when the loader crashes.
>> The documentation of the utility will have to have big red sentences
>> describing each of the missing dependencies.
>> This will make it much harder for the IDE to help the programmer. Now the
>> IDE can detect version conflicts based on references in the POM and can let
>> the developer resolve them.*
>>
> I never said to skip the provided dependencies at all. What I suggested was
> to remove the 'provided' option from the<scope> element in order to limit
> the POM creator to specify the requirements of the artifact only, and not
> hints of how his artifact and its dependencies are going to be assembled or
> deployed. Instead of 'provided' he has to use 'compile' or 'runtime'. This
> way the POM will contain all the necessary information needed but no more.
> Who determines what to assembly and/or how to deploy should be entirely the
> assembly module (the one with EAR packaging type by example). There is
> where the decisions on what to include in the assembly and how to deploy
> must be taken, and not before.
>
I understand your proposal. I am just not sure that you will not find
out that this creates a whole new set of problems.
You have to remember that this is version 3 of Maven and it is used by
thousands of people to develop many different sorts of applications.
The problem that you are addressing has been solved hundreds of times by
Maven users producing EAR packages.
We just produce JARs and WARs in our application but the transitive
dependency version problem and assembly construction issues are the same.
Ron
--
Ron Wheeler
President
Artifact Software Inc
email: rwheeler@artifact-software.com
skype: ronaldmwheeler
phone: 866-970-2435, ext 102
Re: scope management without losing granularity
Posted by Gustavo Pollitzer <gg...@intelap.com>.
Ron said:
> *If a JAR does not contain all of the dependencies that it needs, a
> person using that JAR must have some way to know what is missing and what
> version is required.
> They will only find out at run-time that this jar depends on a missing
> dependency when the loader crashes.
> The documentation of the utility will have to have big red sentences
> describing each of the missing dependencies.
> This will make it much harder for the IDE to help the programmer. Now the
> IDE can detect version conflicts based on references in the POM and can let
> the developer resolve them.*
>
I never said to skip the provided dependencies at all. What I suggested was
to remove the 'provided' option from the <scope> element in order to limit
the POM creator to specify the requirements of the artifact only, and not
hints of how his artifact and its dependencies are going to be assembled or
deployed. Instead of 'provided' he has to use 'compile' or 'runtime'. This
way the POM will contain all the necessary information needed but no more.
Who determines what to assembly and/or how to deploy should be entirely the
assembly module (the one with EAR packaging type by example). There is
where the decisions on what to include in the assembly and how to deploy
must be taken, and not before.
Re: scope management without losing granularity
Posted by Ron Wheeler <rw...@artifact-software.com>.
On 31/10/2011 2:13 PM, Gustavo Pollitzer wrote:
> Ron,
> Thanks again for your clarifications. Now, I have more clear that the
> plugins are free to give the understanding they wish to the POM elements.
> Even the plugins supported by the maven project.
>
> Anyhow, based on what you say, I believe you didn't understand me. Perhaps
> because my bad English.
>
> *On Mon, Oct 31, 2011 at 11:24 AM, Ron Wheeler<
> rwheeler@artifact-software.com> wrote:
> *
>> *A plug-in that builds archives from artifacts created in other projects
>> will not care about scope since anything mentioned as a dependency or
>> included in the list of files to be included will be included.
>> The scope "provided" would be a stupid thing to say as a scope since you
>> could just leave it out of the list if you don't want it in the archive.
>> The scope "compile" is not instructive since you are not going to compile
>> anything.
>> I would expect the author of the plug-in to ignore scope altogether.*
>>
> The scope 'provided' is not pointless. It permits to exclude from the EAR
> an artifact that is a dependency of many of the artifacts that are listed
> for inclusion in the assembly. It avoid the necessity to add a transitive
> dependency exclusion in every expressly included artifact that can depend
> on it.
> In fact, how to do this the proper way was the question that incited me to
> start this discussion. But that is clear for me now.
This would be a particularity of the plug-in and could be true.
It seems that what you are saying is that the assembly plug-in will
expand all of the jars and remove certain classes from the jars that
have been marked as excluded.
> *
> On Mon, Oct 31, 2011 at 11:24 AM, Ron Wheeler<
> rwheeler@artifact-software.com> wrote:
> *
>> *"Provided" only depends on deployment.
>> The fact that it is a "compile" or "provided" dependency at all means that
>> you need the artifact for the compile but when you specify a "provided"
>> dependency, you are telling Maven that it will be provided at deployment
>> in some other way and you asking Maven NOT to stick it in the current
>> artifact.*
>>
> Right. But note that also the "compile" scoped dependencies are not
> packaged along the artifact in many packaging types.
In the "standard" Maven plug-ins that build jars, it will cause them to
be included.
> Anyway, that is what I am trying to say. This is the information supplied
> by the second aspect of the<scope> element I mentioned. This aspect tells
> maven how the dependency will be provided.
> And because the person that
> creates an artifact POM (in opposition to an assembly POM) doesn't have to
> take care if his artifact and the dependencies it requires are going to be
> assembled together or how are they deployed, it should not be specified in
> the artifact's POM.
An interesting point.
If a JAR does not contain all of the dependencies that it needs, a
person using that JAR must have some way to know what is missing and
what version is required.
They will only find out at run-time that this jar depends on a missing
dependency when the loader crashes.
The documentation of the utility will have to have big red sentences
describing each of the missing dependencies.
This will make it much harder for the IDE to help the programmer. Now
the IDE can detect version conflicts based on references in the POM and
can let the developer resolve them.
> The artifact POM merely has to tell maven which dependencies are required
> by the release, which are required for testing, which of them are required
> during runtime only or compilation also, and which of them must be loaded
> by the same class loader than the artifact classes. In short, what it
> requires.
>
> On the other hand, the assembly POM provides the requirements and/or tells
> how they are provided.
> Therefore, the 'provided' option (and much more the 'system' option) must
> be removed from the<scope> element. This information pertains to the
> assembly POM or whatever specifies how to deploy.
System is never used.
> I hope I was clearer this time.
I understand where the motivation for this idea comes from but am
concerned that the problem that it creates is worse than the problem
that it solves.
We used a much clearer way of solving this problem through aggregation
jars that sorted out deployment once for each set of libraries and
reduced the artifact POMs' <dependencies> to a few dependencies that
were carefully managed centrally.
Ron
--
Ron Wheeler
President
Artifact Software Inc
email: rwheeler@artifact-software.com
skype: ronaldmwheeler
phone: 866-970-2435, ext 102
Re: scope management without losing granularity
Posted by Gustavo Pollitzer <gg...@intelap.com>.
Ron,
Thanks again for your clarifications. Now, I have more clear that the
plugins are free to give the understanding they wish to the POM elements.
Even the plugins supported by the maven project.
Anyhow, based on what you say, I believe you didn't understand me. Perhaps
because my bad English.
*On Mon, Oct 31, 2011 at 11:24 AM, Ron Wheeler <
rwheeler@artifact-software.com> wrote:
*
>
> *A plug-in that builds archives from artifacts created in other projects
> will not care about scope since anything mentioned as a dependency or
> included in the list of files to be included will be included.
> The scope "provided" would be a stupid thing to say as a scope since you
> could just leave it out of the list if you don't want it in the archive.
> The scope "compile" is not instructive since you are not going to compile
> anything.
> I would expect the author of the plug-in to ignore scope altogether.*
>
The scope 'provided' is not pointless. It permits to exclude from the EAR
an artifact that is a dependency of many of the artifacts that are listed
for inclusion in the assembly. It avoid the necessity to add a transitive
dependency exclusion in every expressly included artifact that can depend
on it.
In fact, how to do this the proper way was the question that incited me to
start this discussion. But that is clear for me now.
*
On Mon, Oct 31, 2011 at 11:24 AM, Ron Wheeler <
rwheeler@artifact-software.com> wrote:
*
>
> *"Provided" only depends on deployment.
> The fact that it is a "compile" or "provided" dependency at all means that
> you need the artifact for the compile but when you specify a "provided"
> dependency, you are telling Maven that it will be provided at deployment
> in some other way and you asking Maven NOT to stick it in the current
> artifact.*
>
Right. But note that also the "compile" scoped dependencies are not
packaged along the artifact in many packaging types.
Anyway, that is what I am trying to say. This is the information supplied
by the second aspect of the <scope> element I mentioned. This aspect tells
maven how the dependency will be provided. And because the person that
creates an artifact POM (in opposition to an assembly POM) doesn't have to
take care if his artifact and the dependencies it requires are going to be
assembled together or how are they deployed, it should not be specified in
the artifact's POM.
The artifact POM merely has to tell maven which dependencies are required
by the release, which are required for testing, which of them are required
during runtime only or compilation also, and which of them must be loaded
by the same class loader than the artifact classes. In short, what it
requires.
On the other hand, the assembly POM provides the requirements and/or tells
how they are provided.
Therefore, the 'provided' option (and much more the 'system' option) must
be removed from the <scope> element. This information pertains to the
assembly POM or whatever specifies how to deploy.
I hope I was clearer this time.
Re: scope management without losing granularity
Posted by Ron Wheeler <rw...@artifact-software.com>.
On 30/10/2011 5:56 PM, Gustavo Pollitzer wrote:
> Thank you a lot for your time. Your really illuminated my brain. My mistake
> was to try to make the EAR module of my project in such a way that other
> artifacts can depend on it. But that is no the purpose of EAR modules.
Right.
> So, there is no risk to append, after the dependencies intended to add
> content to the EAR, some dependencies to artifacts that are already
> dependencies of the before dependencies just to override its scope to
> 'provided'. The maven-ear-plugin takes advantage of the maven dependency
> management, but uses it for a very different purpose: to make an archive
> and not an artifact to which other artifacts can depend upon. So the
> maven terms has a different meaning in POMs intended to be an artifact to
> which others can depend upon than in POMs intended to build assemblies.
That could be but that is the plug-in author's choice.
The assembly plug-in or the shade plug-in can use a separate file to
determine what to include in the archive.
> Nevertheless, there is something that makes noise in my brain. It would be
> better if the two kinds of dependencies; the ones intended to add content
> to the EAR, let's call them 'content' dependencies, and the ones intended
> to override the scope of the dependencies of the 'content' dependencies;
> would be clearly distinguishable by means of the maven language instead
> of comments.
A plug-in that builds archives from artifacts created in other projects
will not care about scope since anything mentioned as a dependency or
included in the list of files to be included will be included.
The scope "provided" would be a stupid thing to say as a scope since you
could just leave it out of the list if you don't want it in the archive.
The scope "compile" is not instructive since you are not going to
compile anything.
I would expect the author of the plug-in to ignore scope altogether.
>
> I think that the source of this trouble is the low cohesion of the<scope>
> element. It tries to specify two aspects of an artifact with a single
> value. Two aspects that should be independent of each other and that should
> be determined in different circumstances.
>
> - The first aspect is the classification of the dependency as
> required during runtime only or during compilation also. This aspect
> depends only and exclusively on the source code of the artifact for which
> we are specifying the dependencies. It does not depend in any way on the
> deployment.
Not true.
"Provided" only depends on deployment.
The fact that it is a "compile" or "provided" dependency at all means
that you need the artifact for the compile but when you specify a
"provided" dependency, you are telling Maven that it will be provided
at deployment in some other way and you asking Maven NOT to stick it in
the current artifact.
> - And the second aspect tells the packager plugin if it has to add the
> dependency to the archive or not. This aspect has nothing to do with the
> source code, but only with the deployment. The creator of the artifact
> should not necessarily know the way his artifact and their dependencies
> will be deployed, and therefore, this aspect should not be specified by
> him, but by responsible of the deployment trough some kind of descriptor.
> In our case, the EAR module POM.
>
This depends on who wrote the plug-in and what they decided to use as
instructions.
This has nothing to do with Maven since anyone can put whatever logic
they want in their plug-in.
If the plug-in has its own place to list files and artifacts that it
want to manipulate, that will work.
If the author wants to look at the <dependencies> to identify artifacts
to process, that will work.
Don't mix up plug-ins with Maven and be careful about generalizing the
behaviour of plug-ins.
The author has a lot of freedom about how to build a plug-in.
There is a big difference between the core Maven plug-ins that compile
and build artifacts and plug-ins that do assemblies of archives.
You are right that their understanding of <dependencies> are very different.
I hope that this helps.
Ron
--
Ron Wheeler
President
Artifact Software Inc
email: rwheeler@artifact-software.com
skype: ronaldmwheeler
phone: 866-970-2435, ext 102
Re: scope management without losing granularity
Posted by Gustavo Pollitzer <gg...@intelap.com>.
So, I still believe that maven needs improvements in this sense. In my
opinion:
- The <scope> element should be limited to tell only if the dependency
is required during run-time only or during compilation also. Whenever to
include the dependency in an assembly or not should be delegated to the the
descriptor of the assembly. The EAR POM by example.
- A new sub element of the <dependency> element should be added to
specify if the code of the artifact supports that the classes in the
dependency can be loaded by a different class loader or not.
- The content of the packages like EAR, that are not intended to be
depended upon, should not be determined by the <dependencies> element but
by a new element with a different structure. A structure that allows to
exclude a single and a bundle of transitive dependencies from both, a
single component and a group of them. To use the same structure to specify
two so different things causes ambiguities and/or limitations.
Re: scope management without losing granularity
Posted by Gustavo Pollitzer <gg...@intelap.com>.
Thank you a lot for your time. Your really illuminated my brain. My mistake
was to try to make the EAR module of my project in such a way that other
artifacts can depend on it. But that is no the purpose of EAR modules.
So, there is no risk to append, after the dependencies intended to add
content to the EAR, some dependencies to artifacts that are already
dependencies of the before dependencies just to override its scope to
'provided'. The maven-ear-plugin takes advantage of the maven dependency
management, but uses it for a very different purpose: to make an archive
and not an artifact to which other artifacts can depend upon. So the
maven terms has a different meaning in POMs intended to be an artifact to
which others can depend upon than in POMs intended to build assemblies.
Nevertheless, there is something that makes noise in my brain. It would be
better if the two kinds of dependencies; the ones intended to add content
to the EAR, let's call them 'content' dependencies, and the ones intended
to override the scope of the dependencies of the 'content' dependencies;
would be clearly distinguishable by means of the maven language instead
of comments.
I think that the source of this trouble is the low cohesion of the <scope>
element. It tries to specify two aspects of an artifact with a single
value. Two aspects that should be independent of each other and that should
be determined in different circumstances.
- The first aspect is the classification of the dependency as
required during runtime only or during compilation also. This aspect
depends only and exclusively on the source code of the artifact for which
we are specifying the dependencies. It does not depend in any way on the
deployment.
- And the second aspect tells the packager plugin if it has to add the
dependency to the archive or not. This aspect has nothing to do with the
source code, but only with the deployment. The creator of the artifact
should not necessarily know the way his artifact and their dependencies
will be deployed, and therefore, this aspect should not be specified by
him, but by responsible of the deployment trough some kind of descriptor.
In our case, the EAR module POM.
Re: scope management without losing granularity
Posted by Barrie Treloar <ba...@gmail.com>.
On Sun, Oct 30, 2011 at 4:50 AM, Ron Wheeler
<rw...@artifact-software.com> wrote:
> If you want to continue the conversation, you should maybe tell everyone a
> bit about what you are trying to build and why your application structure
> has to be so different from everyone else building the same type of
> application.
> That will get you much better advice since there are probably dozens of
> people in the forum who have built applications to run in exactly the same
> environment.
> If you can tell them where you are deviating from the standard structure,
> they may be able to give you some good advice.
> If you are building a normal web application that runs in one of the normal
> environments, Maven will work very simply as is.
And I will add to Ron's advice - have a read of the free books available at
http://maven.apache.org/articles.html
> According to my knowledge, there is no proper way to override the scope of A3 without specifying its version nor losing granularity.
Also as Ron says you want to have the correct scope defined the first
time so that you only need to override it once for you "library"
artifact.
It is definitely possible to only specify group and artifact with the
new scope to change what was defined in dependencyManagement.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org
Re: scope management without losing granularity
Posted by Ron Wheeler <rw...@artifact-software.com>.
Your example is a little complicated and not exactly expressed in Maven
terms but I can respond to a bit of what you wrote.
In general, you might want to start with what you are trying to build.
Maven is used by thousands on people to build many different types of
applications.
Maven enforces a certain way of looking at the universe and will defeat
you (or make you wish you gave up) if you try to fight it.
See below for specific comments
On 28/10/2011 5:21 PM, G. Gustavo Pollitzer wrote:
> �Hello! I need to do something that, according to what I know, it is
> not supported by maven. Tell me if I am wrong.
> Let BoM be a Bill of Materials (a POM with pom packaging type that,
> apart of the coordinates, only contains a <dependencyManagement>
> element which specifies the version of a bundle of artifacts).
> Let A3 be an artifact contained in BoM (its version is specified in
> the <dependencyManagement> element of BoM).
> Let A2 be third party artifact that depends on A3 with compile scope.
> Let A1 be an artifact that depends on A2 also with compile scope.
> Let E be POM that imports (or inherits from) BoM and whose
> <dependencies> element contains A1.
> Suppose it is needed to override the scope of A3 in E. By example,
> change it to 'provided' because E packaging type is 'ear' and A3 is
> provided by the application server.
> According to my knowledge, there is no proper way to override the
> scope of A3 without specifying its version nor losing granularity.
> If I made use of the <dependencyManagement> element of E to override
> the scope of A3, I would be forced to specify an A3's valid version,
> and that opposes to the "Bill of Materials" pattern.
> If I added A3 as another dependency of E with the desired scope, I
> would fall in the error of forcing E to depend on A3, fact that could
> be true in the current A2 version but may change in the future.
> For the case of the example, the only solution I found is to put A3 as
> an excluded transitive dependency this way:
> <code>
> ...
> <artifactId>E</artifactId>
> ...
> <dependencies>
> ...
> <dependency>
> <groupId>org.test</groupId>
> <artifactId>A2</artifactId>
> <excludes>
> <exclude>
> <groupId>org.test</groupId>
> <artifactId>A3</groupId>
> </exclude>
> <excludes>
> ...
> </dependency>
> </dependencies>
> ...
> </code>
> The drawbacks of this approach are:
> - It only solves the case of the mentioned example where the final
> objective is to avoid A3 be included in the "E.ear".
> - If another artifact, call it X, depended on E with compile scope, it
> would (at least) throw compilation error if X tries to define a class
> that inherits from a class defined in A3.
If X has a dependency on Y, then it should either define the dependency
itself or depend on something that exposes Y. Having it depend on a
project E that excludes Y will not get you Y.
> - If E has many direct dependencies that transitively depend on A3,
> the exclusion would be necessarily and inconveniently repeated in all
> of them.
Not sure that is needs to be true.
You can fix this by building proper libraries that contain exactly what
you want and depend on them.
Probably A3 needs to a "provided" scope dependency in A2 and provided to
all modules once, in a library POM or an application 'core' library that
gets you the common stuff.
Then you don't need the exclusion since it is not included in A2.
http://blog.artifact-software.com/tech/?p=121
> If I am not wrong and the above mentioned is not supported by maven,
> it occurred to me two improvements to solve it: To permit the
> <dependencyManagement> element to contain dependencies whose
> cordinates don't specify the version of artifacts that are already
> managed in a parent's of imported POM's <dependencyManagement>
> element; or to add a new kind of element inside the <dependencies>
> element to manage scope overrides. I prefer the second alternative
> because in the first some granularity is lost because the
> <dependencyManagement> element affects the children also.
>
I would focus on getting your project properly structured and working.
It takes a while to figure out Maven if you come at it very fixed ideas.
First figure out why Maven is doing it the best possible way and what
your project structure should be to get the most out of Maven.
You will likely find that your request is not a good idea.
We have several large portal applications (70+ modules with over 100
third party libraries) and Maven works very effectively in this
environment with very small POM files with no custom plug-ins or any
fancy stuff.
> I hope I am wrong and you illuminate my brain,
You probably are.
If you want to continue the conversation, you should maybe tell everyone
a bit about what you are trying to build and why your application
structure has to be so different from everyone else building the same
type of application.
That will get you much better advice since there are probably dozens of
people in the forum who have built applications to run in exactly the
same environment.
If you can tell them where you are deviating from the standard
structure, they may be able to give you some good advice.
If you are building a normal web application that runs in one of the
normal environments, Maven will work very simply as is.
I hope that this helps.
>
> Happily,
>
> Gustavo Pollitzer
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
>
>
--
Ron Wheeler
President
Artifact Software Inc
email: rwheeler@artifact-software.com
skype: ronaldmwheeler
phone: 866-970-2435, ext 102