Feature #9483
improve build scripts to allow better dependecy updates
0%
History
#1 Updated by Ovidiu Maxiniuc over 1 year ago
Currently, FWD building tool (ant/gradlew) will look for changes in required libraries and only download new revisions at the moment of the build. The problem is that, with the switch to newer libraries (jars) some APIs become deprecated or even invalid. Keeping the old jars will cause a race condition at class lading time and, usually, the older, having a lower number, will be scanned first and the new one will be skipped. This is the case of our custom build H2 driver, causing unexpected runtime errors later when FWD tries to access new feature, unavailable in the old library.
In conclusion, the building tool must be aware of the library upgrades and drop the old revisions. If this cannot be done automatically, we need to create a new target which would manually remove all libraries. I am not sure whether this should be set as a dependency of normal build because the large amount of the jars. Also dropping all jars will also make the build impossible when working offline.
#2 Updated by Greg Shah over 1 year ago
+Hynek, +Roger, +Tomasz
#3 Updated by Tomasz Domin over 1 year ago
Isnt that enough to clean fwd/build/lib and app/deploy/lib on components update ? Library files are cached anyway by gradle, so we can even do that on every build.
If so I think we are missing deploy.clean target in standard application build.xml file.
For FWD there is clean target that cleans build/lib.
#4 Updated by Roger Borrello over 1 year ago
Tomasz Domin wrote:
Isnt that enough to clean
fwd/build/libandapp/deploy/libon components update ? Library files are cached anyway bygradle, so we can even do that on every build.If so I think we are missing
deploy.cleantarget in standard applicationbuild.xmlfile.
ForFWDthere iscleantarget that cleansbuild/lib.
This is one reason I developed the "deployapp" targets in projects and -a option to install_spawner.sh, so that we don't copy dependency jar files around. Rather, their location in FWD_LIB allows the server.sh script to add them to the classpath separately.
With respect to building FWD itself, I researched some approaches for discussion.
1. Automate Cleanup of Old Jars¶
- Implement a cleanup mechanism in the build tools (Ant or Gradle) to ensure that outdated libraries are removed automatically. For example:
- Gradle: Use the clean task to delete the
libsdirectory or specific jars before resolving dependencies. - Ant: Add a custom target to delete outdated jars based on a timestamp or version mismatch.
- Gradle: Use the clean task to delete the
Example in ant
<target name="clean-libs" description="Clean outdated libraries">
<delete>
<fileset dir="lib" includes="**/*.jar" excludes="specific-exclusions-if-needed"/>
</delete>
</target>
Example in gradle
tasks.register('cleanLibs')
{
doLast
{
file('libs').deleteDir()
}
}
- Optional: Integrate this step into the main build process as a dependency, but allow it to be skipped with a flag (e.g.,
-PskipClean).
2. Version-Based Jar Management¶
- Ensure all dependencies in the
libsdirectory are versioned explicitly. - When a library is upgraded, replace the older version with the new one and remove the old version from the repository or the build path.
Gradle Example: Use dependency resolution rules to reject outdated versions:
configurations.all
{
resolutionStrategy
{
eachDependency
{ details ->
if (details.requested.group == 'com.h2database' && details.requested.name == 'h2')
{
details.useVersion('2.1.0') // Ensure only the latest version is used
}
}
}
}
Ant Example: Maintain an explicit list of jars in the build.xml and ensure old versions are excluded.
3. Warn About Deprecated APIs During Build¶
- Configure the build process to emit warnings when deprecated APIs are detected.
- Gradle can enforce strict checks for deprecated or invalid APIs using
-Werroror a lint plugin. - For Ant, use a static analysis tool (e.g., PMD or Checkstyle) to identify deprecated API usage.
4. Offline Build Support¶
- If removing jars disrupts offline builds, ensure a mechanism to cache dependencies:
- Gradle: Enable offline mode (
--offline) and use a local dependency repository. - Ant: Create a local Maven repository or store jars in a dedicated directory.
- Gradle: Enable offline mode (
5. Introduce a "Purge and Refresh" Target¶
Create a target/task to remove all libraries and redownload them in one step, ensuring a clean state when required.
Ant Example:
<target name="purge-and-refresh" depends="clean-libs">
<antcall target="download-libs"/>
</target>
Gradle Example:
tasks.register('purgeAndRefresh')
{
dependsOn 'cleanLibs'
doLast
{
exec
{
commandLine 'gradle', 'build', '--refresh-dependencies'
}
}
}
6. Dependency Locking¶
- Use dependency locking to ensure consistent library versions across builds:
- Gradle: Use the
dependency-lockplugin to lock library versions. - Ant: Generate a
dependencies.propertiesfile with explicit version mappings.
- Gradle: Use the