You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@maven.apache.org by "Thomas R." <de...@email.de> on 2007/03/23 12:18:41 UTC

Problem with Scope of Transitive Dependencies

Hello,

we are developing a very large project with a layered architecture. We decided to use Maven (Version 2.0.4) in order to have a good dependency-management. We are now facing the following problem with transitive dependencies:

Consider following (simplified) example: We have a module DAO and a module SERVICE. The module SERVICE depends on DAO. Furthermore the module DAO depends on Hibernate. We now want to ensure that there is no compilation-dependency from SERVICE to Hibernate. This is the only way to really make sure that no developer uses any Hibernate-classes in the SERVICE-module "accidentally". There are many other examples like this where we do not want a transitive dependency to get the scope "compile".

In the maven documentation we found the following comment under "Transitive Dependencies" / "Dependency Scope" for the resulting scope when DAO uses Hibernate in scope "compile" and SERVICE uses "DAO" in scope "compile":
"(*) Note: it is intended that this should be runtime instead, so that all compile dependencies must be explicitly listed - however, there is the case where the library you depend on extends a class from another library, forcing you to have available at compile time. For this reason, compile time dependencies remain as compile scope even when they are transitive."
(see http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html)

For a large project with many (sometimes inexperienced) developers all over the world this makes it impossible to retain full control about the proper compliance of the basic architecture principles. So it is impossible for us to use transitive dependencies so that we are looking for an alternative. We see the following possibilities:

1.) Patch Maven: We could patch the maven-Installation by replacing the file lib/maven-artifact-2.0.4.jar with an own implementation of the class that computes the resulting scope. We would like to avoid this since every developer would have to do this manually, so that we would do this only as last option when we see that there is no other possibility. 
Is it planned to change the transitive scope in this case to "test" resp. "runtime" later? Or perhaps will there be a possibility to have influence on the resulting scope per configuration in the pom.xml?

2.) Inheritance: We don't use transitive dependencies at all. We always explicitly define all dependencies in a module. In order to avoid duplication we define base projects. Each base project inherits a special set of standard dependencies. Main disadvantage is that this gets ugly when we need different combinations of dependency-sets for different modules, since the inheritance-tree will get larger and larger...

3.) XML-include:  Same as 2. but we do not use inheritance but XML-include for defining dependency-sets (e.g. <!ENTITY hibernate-runtime-dependencies SYSTEM "../dependency-sets/hibernate-runtime-dependencies.xml">) and import these sets within the dependencies-tag in the pom.xml via "&hibernate-runtime-dependencies;".
This would  be much more flexible than 2. since arbitrary combinations of dependency-sets could be used within a single module. Unfortunalely the maven-XML-Parser seems not to support this. Is there a possibility to switch on this XML-feature?

4.) Custom Plugin: We could write an own maven-plugin that gives us the possibility to define our own dependency-sets. This plugin could extend the dependencies of a module at maven-runtime. We could use special properties to define the dependency-sets of a module to be used in addition to the dependencies that are defined within the dependencies-tag of the pom.xml. We are not sure if this is possible since the additional dependencies of course must be available during all phases of all lifecycles (at least default- and site-lifecycle).

Currently we are using inheritance as a workaroud. We are desperately looking for a better solution of this since our project now is coming into a phase where it will grow fast and there is a big danger that we loose overview about our dependencies. I would be very very thankful if anyone could help me with this.

Thanks in advance,
Thomas


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org


Re: Problem with Scope of Transitive Dependencies

Posted by Jason van Zyl <ja...@maven.org>.
On 23 Mar 07, at 7:18 AM 23 Mar 07, Thomas R. wrote:

> Hello,
>
> we are developing a very large project with a layered architecture.  
> We decided to use Maven (Version 2.0.4) in order to have a good  
> dependency-management. We are now facing the following problem with  
> transitive dependencies:
>
> Consider following (simplified) example: We have a module DAO and a  
> module SERVICE. The module SERVICE depends on DAO. Furthermore the  
> module DAO depends on Hibernate. We now want to ensure that there  
> is no compilation-dependency from SERVICE to Hibernate. This is the  
> only way to really make sure that no developer uses any Hibernate- 
> classes in the SERVICE-module "accidentally". There are many other  
> examples like this where we do not want a transitive dependency to  
> get the scope "compile".
>

Your DAO should have an API, the service should only depend on the  
DAO API. The only thing your developers would see are the DAO  
interfaces in their IDE for example. I am assuming that your  
developers must see the DAO API in order for them to do any work? If  
you separate the interface from the implementation, have 2 JARs, and  
then only specify the specific implementations in your runtime  
distributions then your developers will be shielded from the specific  
implementations. In your case Hibernate.

It boils down to mixing your concerns. In this case interface with  
implementation details.

What are you using for your runtime system?

For testing services what I have done in cases like your is to make a  
mock DAO with some test data so that developers can exercise their  
service in tests but still not be exposed to a real implementation.  
If you want them to test with the Hibernate then you can specify that  
as a test = scope for that particular service.

What's below is far too complicated and not necessary. Separating  
your API from implementations is the way to go. And if you ever want  
to create an implementation of your DAO based on JPA for example then  
you don't have to then scrape our the interfaces you've bound up with  
Hibernate in one JAR. Separating these JARs goes a long way to having  
a flexible architecture and helps enforce the rules you want for your  
developers.

Jason.

> In the maven documentation we found the following comment under  
> "Transitive Dependencies" / "Dependency Scope" for the resulting  
> scope when DAO uses Hibernate in scope "compile" and SERVICE uses  
> "DAO" in scope "compile":
> "(*) Note: it is intended that this should be runtime instead, so  
> that all compile dependencies must be explicitly listed - however,  
> there is the case where the library you depend on extends a class  
> from another library, forcing you to have available at compile  
> time. For this reason, compile time dependencies remain as compile  
> scope even when they are transitive."
> (see http://maven.apache.org/guides/introduction/introduction-to- 
> dependency-mechanism.html)
>
> For a large project with many (sometimes inexperienced) developers  
> all over the world this makes it impossible to retain full control  
> about the proper compliance of the basic architecture principles.  
> So it is impossible for us to use transitive dependencies so that  
> we are looking for an alternative. We see the following possibilities:
>
> 1.) Patch Maven: We could patch the maven-Installation by replacing  
> the file lib/maven-artifact-2.0.4.jar with an own implementation of  
> the class that computes the resulting scope. We would like to avoid  
> this since every developer would have to do this manually, so that  
> we would do this only as last option when we see that there is no  
> other possibility.
> Is it planned to change the transitive scope in this case to "test"  
> resp. "runtime" later? Or perhaps will there be a possibility to  
> have influence on the resulting scope per configuration in the  
> pom.xml?
>
> 2.) Inheritance: We don't use transitive dependencies at all. We  
> always explicitly define all dependencies in a module. In order to  
> avoid duplication we define base projects. Each base project  
> inherits a special set of standard dependencies. Main disadvantage  
> is that this gets ugly when we need different combinations of  
> dependency-sets for different modules, since the inheritance-tree  
> will get larger and larger...
>
> 3.) XML-include:  Same as 2. but we do not use inheritance but XML- 
> include for defining dependency-sets (e.g. <!ENTITY hibernate- 
> runtime-dependencies SYSTEM "../dependency-sets/hibernate-runtime- 
> dependencies.xml">) and import these sets within the dependencies- 
> tag in the pom.xml via "&hibernate-runtime-dependencies;".
> This would  be much more flexible than 2. since arbitrary  
> combinations of dependency-sets could be used within a single  
> module. Unfortunalely the maven-XML-Parser seems not to support  
> this. Is there a possibility to switch on this XML-feature?
>
> 4.) Custom Plugin: We could write an own maven-plugin that gives us  
> the possibility to define our own dependency-sets. This plugin  
> could extend the dependencies of a module at maven-runtime. We  
> could use special properties to define the dependency-sets of a  
> module to be used in addition to the dependencies that are defined  
> within the dependencies-tag of the pom.xml. We are not sure if this  
> is possible since the additional dependencies of course must be  
> available during all phases of all lifecycles (at least default-  
> and site-lifecycle).
>
> Currently we are using inheritance as a workaroud. We are  
> desperately looking for a better solution of this since our project  
> now is coming into a phase where it will grow fast and there is a  
> big danger that we loose overview about our dependencies. I would  
> be very very thankful if anyone could help me with this.
>
> Thanks in advance,
> Thomas
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
> For additional commands, e-mail: dev-help@maven.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org