GCube Maven BOMs
What is a BOM
When dealing with large projects like in the case of gCube, it's fondamental to introduce mechanism in order to mitigate the anarchy of developers in using third party dependencies or even other teams artifacts versions.
As described in the maven documentation [] there is a standard way to define the base artifacts of a project by implementing a BOM ( BIll of Materials)
The Maven BOM is a pom only component which fixes the dependencies and base versions of a component which imports it.
The GHN Maven BOM
In the case of gCube, each gCube service is deployed and runs in an old fashion container (GHN) based on globus WS-Core 4.0, which unfortunately does not implement separate classloaders for each deployed component as for the latest web service containers ( like OGSi or tomcat) .
Therefore we have to deal with a flat classloader schema which leads very easily to artifact clashes, especially clashes of different version of the same artifact. In order to avoid any possible clash or at least inform a gCube developer that there might be clashes once the service is deployed in a container, a Maven BOM for the GHN has been developed.
The BOM contains all the possible libraries that are contained in a standard GHN distribution ( there will be a secure version soon), specifying the version of the third party libraries and open ranges for the gCube one ( in order to have the latest version available).
The maven BOM component is available on the gCube SVN trunk at [] and from the gCube maven repo.
Every gCube component being a final deployment unit on a GHN container ( Service or Plugin) that adopt Maven should include the maven BOM in its parent module pom. In particular it should include the BOM in the dependencies management section :
<dependencyManagement> <dependencies> ... <dependency> <groupId>org.gcube.distribution</groupId> <artifactId>maven-bom</artifactId> <version>LATEST</version> <type>pom</type> <scope>import</scope> </dependency> ... </dependencies> </dependencyManagement>
The scope import implies that the pom declarations within the maven BOM are imported in the service parent pom and its modules. In particular this means that all dependencies declared in the maven modules are managed by the ones declared in the BOM :
1) Each dependency declared in a module which is also contained in the BOM should be specified withut the version parameter, i.e.:
<dependency> <groupId>org.gcube.core</groupId> <artifactId>gcf</artifactId> </dependency>
this way the dependency version are managed by a single component and they are always aligned to the latest version available. In case the developer is going to specify a version for a managed dependency it will be highlighted directly by the IDE ( i.e. Ecplise) :
This warning can be ignored of course but it's highly recommended not to include a version different from the one managed by the BOM. In the case a new version of an artifact is needed ( especially third-party) so the override of the managed version is not evitable, accurate test must be conducted in order to understand if the new version of the artifact can be compatibly installed on the GHN container.
2) Each service transitive dependency are going to be also managed by the one specified in the BOM. This means that if a dependency of the service depends on an artifact which is present on the BOM, the version specified on the BOM is going to be used.
It's easy to check this behavior by looking at the Dependency Hierarchy section available in Eclipse (e.g. slf4j from 1.6.1 to 1.6.4):
3) Each service transitive dependency managed by the one specified in the BOM are going to be declared with scope provided (e.g. common-scope from compile to provided):
This means not only that the gCube Enabling Layer is not going to deploy those dependencies on a GHN when dynamically deploying the service on the infra but also they are going to be excluded when generating a service full-gar.
The Portal Maven BOM
In the case of Portlets, each gCube portlet is deployed and runs in a customised version of Liferay 6.0.6, the gCube Portal. The base liferay installation has been extended by integrating:
- GHN libraries : GHN contains also the client side libraries to communicate with the Infrastructure services
- ASL libraries : the Application Support Layer is a common layer integrated by each portlet which provides common facilities like session and scope management, etc
- HomeLibrary and Workspace base libs : libraries for the management of user workspace
- Third Party Libs: Libraries which are runtime dependencies of the above gcube components.
The above components are loaded in the portal common classloader this means that the related classes are shared among each portlet class & dependency deployed in the application classloader.
For this reason the definition of a BOM collecting the information regarding the above components is also quite important cause it avoids to:
- depend on components versions different than the one deployed in the gCube portal, therefore avoiding library clashes
- package on each portlet war the components that are already deployed un the gCube Portal ( the BOM declares this dependencies with provided scope)
The maven Portal BOM component is available on the gCube SVN trunk at [] and from the gCube maven repo.
In order to include the portal Maven BOM on each portlet the following Dependencies Management snippet should be included in the portlet pom:
<dependencyManagement> <dependencies> ... <dependency> <groupId>org.gcube.distribution</groupId> <artifactId>maven-portal-bom</artifactId> <version>LATEST</version> <type>pom</type> <scope>import</scope> </dependency> ... </dependencies> </dependencyManagement>
As already said a number of benefits come from the inclusion of the BOM in a portlet pom and they are better explained in the previous sections on GHN Maven BOM points 1,2,3.
Each component ( portlet or service ) which is using a gCube Maven BOM within its pom should explicitly declared a dependency on ETICS.
In the case of services ( and stubs if the BOM is imported on the parent pom) the following component should be included among the dependencies
while in the case of a portlet the following dependency is needed:
unfortunately it was not possible to add a dependency transparently ( on maven-parent or gcf) cause not every components are requested to include BOMs, but only portlets and services.