Optimizing Continuous Development By Detecting and Preventing Unnecessary Content Generation
Talank Baral, Shanto Rahman, Bala Naren Chanumolu,
Basak Balci,Tuna Tuncer, August Shi, Wing Lam
CCF-2145774
Developer Anecdote
2
Servers
4:15 PM
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml: Defines project dependencies and configuration for Maven builds
…� static int add() {
- ts.addRow(“”);� return ts.size();
…
Build code and
run tests using
pom.xml
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
4:17 PM
Developer’s laptop
Developer Anecdote
3
Servers
…� static int add() {
- ts.addRow(“”);� return ts.size();
…
…� static int add() {
- ts.addRow(“”);
+ ts.addRow(r);� return ts.size();
…
4:15 PM
4:25 PM
Build code and
run tests using
pom.xml
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
Build code and
run tests using
pom.xml
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
Servers
Build code and run tests �using pom.xml and YAML file
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
YAML file
4:27 PM
4:17 PM
…�- static int add() {
+ static int add(r) {
- ts.addRow(“”);
+ ts.addRow(r);� return ts.size();
…
Developer’s laptop
…
4:35 PM
6:10 PM
6:15 PM
Developer Anecdote
4
…�- static int add() {
+ static int add(r) {
- ts.addRow(“”);
+ ts.addRow(r);� return ts.size();
…
Servers
…� static int add() {
- ts.addRow(“”);� return ts.size();
…
…� static int add() {
- ts.addRow(“”);
+ ts.addRow(r);� return ts.size();
…
4:15 PM
4:25 PM
Build code and
run tests using
pom.xml
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
Build code and
run tests using
pom.xml
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
Servers
Build code and run tests �using pom.xml and YAML file
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
…
4:27 PM
4:17 PM
6:15 PM
Developer’s laptop
4:35 PM
6:10 PM
YAML file
YAML file: Defines what CD build should do on server
Developer Anecdote
5
Servers
…� static int add() {
- ts.addRow(“”);� return ts.size();
…
…� static int add() {
- ts.addRow(“”);
+ ts.addRow(r);� return ts.size();
…
4:15 PM
4:25 PM
Build code and
run tests using
pom.xml
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
Build code and
run tests using
pom.xml
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
Servers
Build code and run tests �using pom.xml and YAML file
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
YAML file
4:27 PM
4:17 PM
…�- static int add() {
+ static int add(r) {
- ts.addRow(“”);
+ ts.addRow(r);� return ts.size();
…
6:15 PM
Developer’s laptop
…
4:35 PM
Merged time: 6:30 PM
Total time: 2h 15min
6:10 PM
Developer Anecdote
6
…
…�- static int add() {
+ static int add(r) {
- ts.addRow(“”);
+ ts.addRow(r);� return ts.size();
…
Servers
…� static int add() {
- ts.addRow(“”);� return ts.size();
…
…� static int add() {
- ts.addRow(“”);
+ ts.addRow(r);� return ts.size();
…
Build code and
run tests using
pom.xml
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
Build code and
run tests using
pom.xml
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
Servers
Build code and run tests �using pom.xml and YAML file
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
YAML file
Developer’s laptop
4:15 PM
4:25 PM
4:27 PM
4:17 PM
6:15 PM
4:35 PM
6:10 PM
Merged time: 6:30 PM
Total time: 2h 15min
CD builds can be expensive to run, especially if they run unnecessary tasks �to generate �unnecessary files.
2 min.
2 min.
5 min.
8 min.
8 min.
15 min.
Coding: 2+2+...+5
Building: 8+8+...+15
What is unnecessary?
7
unnecessary?
….�$ mvn -B package --file pom.xml
Coverage Report
$ mvn -B package --file pom.xml
Coverage Report
Summary
Anything that is destroyed without being accessed is unnecessary
TEMPORARY�Machine
…�<plugin>
…
jacoco-maven-plugin
…
</plugin>�…
pom.xml
Local Build
CD Build
Developer’s laptop
Cloud machine
Configuration of CD
8
name: Java CI with Maven
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
java: [8, 11]
name: java ${{ matrix.java }} building ...
steps:
- uses: actions/checkout@v3
- name: Set up Java ${{ matrix.java }}
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java }}
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn -B package --file pom.xml
We can avoid creation of unnecessary:
To save over 14% of the step runtime!
-DdisableXmlReport=true -Djacoco.skip=true -Dpmd.skip=true
[1] https://github.com/JSQLParser/JSqlParser/blob/b7e5c151df37f5eb5c0e46f7321e19daeb7b9863/.github/workflows/maven.yml
Workflow name and events to trigger the build
Specify OS and java versions to build a job �named “build”
Setup steps
Step to run mvn tests
These changes affect only the CD build and does not affect developers’ local build!
Our Research
9
Goal: Optimize Continuous Development (CD) builds by not creating or modifying unnecessary files to speed up runtime. �To help with this goal, we
OptCD
10
Servers
Developer’s laptop
OptCD
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
YAML file
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
YAML file
OptCD
11
Servers
Developer’s laptop
OptCD
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
YAML file
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
YAML file
OptCD
12
Servers
Developer’s laptop
OptCD
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
YAML file
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
YAML file
OptCD
13
Servers
Developer’s laptop
OptCD
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
YAML file
…�<plugin>
… jacoco-maven-plugin
…
</plugin>�…
pom.xml
YAML file
14
Log
Unused Files
Unused Directories
OptCD Overview
15
Log
Unused Files
Unused Directories
OptCD Overview
16
GitHub Actions YAML
Log
Unused Files
Modified GitHub Actions YAML
Plugins from pom.xml
Unused Directories
Plugins from pom.xml
Modified pom.xml
Runs instrumented YAML once, which:
OptCD Logger
With these rules, the Classifier identifies unnecessary files from the logs generated by the Logger
17
GitHub Actions YAML
Log
Unused Files
Modified GitHub Actions YAML
Plugins from pom.xml
Unused Directories
Plugins from pom.xml
Modified pom.xml
Unnecessary files are the files generated and written to during the build, but never read from later
Created
Modified
Accessed
Necessary file
Unnecessary file
Necessary file
Unnecessary file
echo "abc" >> file.txt
Created, Modified but not Accessed
cat file.txt
Not Modified but Accessed
OptCD Classifier
Clusters unnecessary files into unnecessary directories
18
GitHub Actions YAML
Log
Unused Files
Modified GitHub Actions YAML
Plugins from pom.xml
Unused Directories
Plugins from pom.xml
Modified pom.xml
Plugins modify multiple files. Trying to disable an entire directory is faster than attempting to disable each file individually.
├── target
├── classes
│ ├── META-INF
│ ├── MANIFEST.MF
├── site
│ ├── CCJSqlParser.java.html
│ ├── CCJSqlParserTokenManager.html
├── jacoco
│ ├── jacoco.xml
│ ├── net.sf.jsqlparser.parser
├── javadoc
│ ├── ClassName.html
├── checkstyle-result.xml
../target/jacoco is unnecessary
../target/site is necessary
../target/javadoc is necessary
../target is necessary
Majority of unused files are solely in unnecessary directories
Unnecessary directories
Necessary directory
= Unnecessary file
= Necessary file
OptCD Clusterer
19
GitHub Actions YAML
Log
Unused Files
Modified GitHub Actions YAML
Plugins from pom.xml
Unused Directories
Plugins from pom.xml
Modified pom.xml
Three methods:
Mapper searches for plugin responsible for creation of unnecessary directory
OptCD Mapper
Information Retrieval method:
20
GitHub Actions YAML
Log
Unused Files
Modified GitHub Actions YAML
Plugins from pom.xml
Unused Directories
Plugins from pom.xml
Modified pom.xml
Maven-resources-plugin:3.3.0;
maven-surefire-plugin:3.0.0-M7;
Maven-compiler-plugin:3.10.1;
Maven-bundle-plugin:5.1.8;
Build-helper-maven-plugin:3.2.0;
Maven-checkstyle-plugin:3.1.0;
Maven-pmd-plugin:3.19.0;
Jacoco-maven-plugin:0.8.8;
Maven-site-plugin:3.12.1;
Maven-source-plugin:3.2.1;
Javacc-maven-plugin:3.0.3;
License-maven-plugin:2.0.0;
maven-javadoc-plugin:3.4.1
Ranked #1
Ranked #2
OptCD Mapper
../target/jacoco is unnecessary
../target/site is necessary
../target/javadoc is necessary
../target is necessary
ChatGPT method:
21
GitHub Actions YAML
Log
Unused Files
Modified GitHub Actions YAML
Plugins from pom.xml
Unused Directories
Plugins from pom.xml
Modified pom.xml
OptCD Mapper
Ranked list of plugins
ask to rank plugins
Inputs:
Output:
Log Search method:
22
GitHub Actions YAML
Log
Unused Files
Modified GitHub Actions YAML
Plugins from pom.xml
Unused Directories
Plugins from pom.xml
Modified pom.xml
Java 8 building … Build with Maven 2023-08-07T02:32:45.3833432Z [INFO] --- jacoco-maven-plugin:0.8.7:prepare-agent (default) @ jsqlparser ---
Java 8 building … Build with Maven 2023-08-07T02:34:36.4448210Z [INFO] — jacoco-maven-plugin:0.8.7:prepare-agent (default) @ jsqlparser —
OptCD Mapper
Example Logger log
Example GitHub Actions build log
23
GitHub Actions YAML
Log
Unused Files
Modified GitHub Actions YAML
Plugins from pom.xml
Unused Directories
Plugins from pom.xml
Modified pom.xml
Ask ChatGPT to find a fix for the Maven command in the YAML file
ask argument to add
OptCD Fixer
Inputs:
Argument to update command
Output:
24
GitHub Actions YAML
Log
Unused Files
Unused Directories
Plugins from pom.xml
Plugins from pom.xml
Modified pom.xml
Modified GitHub Actions YAML
OptCD Overview
Research Questions on 22 GitHub Open-Source Projects
25
Conclusion
Solution: We present OptCD, a technique to dynamically detect unnecessary work within CD builds, reducing build runtime and enhancing efficiency
26
Problem: The execution of unnecessary plugins and generation of unnecessary directories in builds waste developers’ time and CD resources
Wing Lam <winglam@gmu.edu>