One of the key aspects of a Source Control Manager (SCM) system is to give the possibility to retrieve and restore a previous state of our application. For example, we must be able to rebuild our application to reproduce, understand and fix an issue met by a customer using 2 year old version of the application.
Unfortunately, having access to our 2 years old source code might not be enough to rebuild the application. Actually, today most applications reference frameworks coming from a tiered organization like Open Source projects or subcontractors. These frameworks are generally organized in a set of libraries, for example JAR files, containing the binary code and, sometimes, the source code or the API documentation.
Of course, each of these frameworks has its own life cycle. So, if we don’t recall at some point which version of the framework we were using when we built our application 2 years ago, it might be hard to rebuild the application 2 years later.
Manage framework versions
To fix such issue we have 2 main options:
- Store the framework version number in our own code with the hope that each time we will have to rebuild the application, all framework versions we used to build our application will be available and accessible either on the Internet or the Intranet.
- Store and baseline the framework library files with our source code into the SCM to be sure to retrieve those resources when it will be required.
Storing version numbers
Storing the version numbers has a huge advantage: the SCM footprint will only grow with the size of the application source code. In other words, the SCM footprint will not depend on the library footprint used by the application.
On the other hand, this option requires a very strict and heavy management of these version numbers. Actually, if a team decides to move from the version N to the version N+1 of a framework, it will have to inform all the other teams of this move forcing them to do the same move to stay in sync.
To minimize such impact, we could centralize these version numbers. Fine but what will happen if this same team wants to move the version N+1 on some incubator project while the other teams have to stay with the current version?
This approach is often used by Maven users (http://maven.apache.org/) and this makes perfectly sense for a build engine like Maven when it is not used jointly with an SCM system like the Jazz SCM.
Actually, if the resources, source code or libraries, are not already available, Maven strategy will consist of pulling missing resources (cf generate-sources and generate-resources goals). Obviously, in such cases, you need to know the version number of the resource you are pulling to be sure to build against the correct resources.
In RTC, the build master can specify the repository workspace containing the resources to download for the build. So, when the Jazz Build Engine will run the Build Request, if the repository workspace is specified, it will pull into target machine this repository workspace, i.e. the current resources contained in the repository workspace.
This approach provides much more flexibility and it dramatically simplifies the management of these version numbers. Actually, the version numbers are managed at the level of the repository workspace which is an artifact of the SCM which is perfectly the place to manage such information.
So if we store and baseline these framework libraries, as any other resource, into the Jazz SCM, it is easy to make a snapshot of all the resources used to build an application, including the used framework libraries. Later on, it will be obvious to use this snapshot to retrieve all these resources and rebuild the corresponding application.
The rest of this post will describe how to use the Eclipse platform coupled to the Jazz SCM to manage, access and store the framework libraries.
Storing libraries in RTC: an example
Let assume we are building an application which requires the Apache HTTP Client. The Apache documentation tells us that to reuse this framework, the developer needs to load and deploy two Apache HTTP components named “Core” and “Client”.
Each of these components contains two JARs:
- The Core component contains httpcore-xxx.jar and httpcore-nio-xxx.jar,
- The Client component contains httpclient-xxx.jar and httpmime-xxx.jar.
Organizing JARs into Eclipse projects
For each of these Apache components we create an Eclipse Java project to store the corresponding JARs. We could store all these JARs into one unique Eclipse project but we wanted to respect the library organization suggested by the Apache project. So:
- For the Core component, we create an Eclipse Java project named org.apache.http.
- In this project we add a simple folder named lib and
- In this lib folder we add the files httpcore-xxx.jar and httpcore-nio-xxx.jar.
- For the Client component, we create another Eclipse Java project named org.apache.http.client
- In this project we add a folder named lib and
- In this lib folder we add the files httpclient-xxx.jar and httpmime-xxx.jar.
Make the JARs visible by the other Eclipse projects
For now the jars are simple files stored in an Eclipse project. We need now to declare them as JARs in the build path and then make them visible by other Eclipse projects
- Edit the Build path of the first project org.apache.http
- In the Libraries tab, add the JARs of the current project (httpcore-xxx.jar and httpcore-nio-xxx.jar)
- In the same Libraries tab, remove the current JRE System Library which is useless
- Switch to the Order and Export tab, check the added JARs to make them visible outside of the current project
- Close the Properties dialog view.
- Repeat the steps 1 to 5 for the second project org.apache.http.client
At this point these Eclipse projects should look like this in the Package Explorer:
Now, any Eclipse Java project having these projects in its Build path will have access contained classes.
Storing JARs in Rational Team Concert
At this point, we can store these “JAR projects” into the Jazz SCM. Because these JARs should have the same lifecycle for the end users, we will store them under the same SCM component.
- Select both projects in the Package Explorer,
- Select the context menu item Team > Share project… to launch the Share project wizard.
- Select Jazz Source Control in the first page of the wizard and press Next
- On the Select Component page, select or create the component which will group these two Eclipse projects.
- Confirm the projects to store in the component by checking them in the Projects page and press Next
- Press Finish
- From the pending Changes view, select the component containing the JAR project and create a baseline
- For memory, name this baseline with the version number of framework you have grabbed.
- Deliver the baseline into the Flow Target Stream
At this point, any team will be able to reuse in a Stream this component baseline like any other component baseline.
Knowing that each Jazz build takes a snapshot of component baselines used for a build, it will be easy to know and retrieve the jars used for a particular release.
Later on, if a team needs to move to a newer version of the Apache HTTP Client, they will only need to update the Eclipse projects with the newer libraries, deliver the changes and make a new baseline.
Even if the approach of storing JARs in RTC seems to be space consuming, it is a good approach to guarantee the fact we will be able later on rebuild an application using all the resources it used originally.
If it is strategic, some users might even decide to store in RTC the compiler they used to compile the source code.
Keep in mind that RTC doesn’t duplicate resources if, for example, a new basely of a component containing JARs has changed only one file. It means that the storage will be always optimum.
Keep also in mind that RTC is evolving every day and it will soon be possible to delete useless component baselines, please see:
- 93126: Enable the deletion of components from the RTC Client
- 89619: Provide operation to delete a particular version and an operation to delete a versionable and all of its states from the repository
I hope it will help.