I worked on a project that uses a framework. To add a new sub class I had to make the base class, that is part of the framework, open for extension. I was able to compile the framework on my own without the need to create a local artifact repository then create a new artifact and new version by the following steps:
- using a composite build
- substitute the dependency
- convert dependent project to a gradle project
Composite Build
A composite build is a build that consists of multiple builds. It’s like a project with submodules but on the build level.
Substitute Dependency
One use case for dependency substitution is to use a locally developed version of a module in place of one that is downloaded from an external repository. This could be useful for testing a local, patched version of a dependency.
The module to be replaced can be declared with or without a version specified. By default, Gradle will configure each included build in order to determine the dependencies it can provide. The algorithm for doing this is very simple: Gradle will inspect the group and name for the projects in the included build, and substitute project dependencies for any external dependency matching ${project.group}:${project.name}
.
In the build.gradle you already have a dependency, because you have worked with the framework already.
1 2 3 | dependencies { compile 'org.sample:theframework:1.8.0' } |
Now we want to replace this dependency with full control over the source code. Add the following to the settings.gradle to declare a composite build and substitute a dependency with that build.
1 2 3 4 5 6 7 | rootProject.name = 'app' includeBuild('./modules/theframework') { dependencySubstitution { substitute module('org.sample:theframework') with project(':') } } |
Convert Dependency to Gradle Project
In my case the framework is using maven as build system. This won’t work so I have to convert the maven project to a gradle project first.
Checkout the framework from source into the directory specified in inlucdeBuild. In my case that is ./modules/theframework.
1 2 3 | git clone modules/theframework cd modules/theframework gradle init |
Now we have the gradle project. Review the generated modules/theframework/build.gradle (especially the sourceCompatibility and targetCompatibility). The project should compile fine on it’s own.
Develop
We have everything set up now. Make your changes to the dependency you have full control about now. Work on your own project and figure out changes that are required to the framework and bring them back to the upstream framework codebase via pull request.