
CS 3100: Program Design and Implementation II
Lecture 23: Open Source Frameworks
©2026 Jonathan Bell & Ellen Spertus, CC-BY-SA
Announcements
-
You may not have gotten the team you expected because one of your requested teammates did not complete the survey.
-
Keep an eye out for important Canvas announcements.
Poll: Have you had a chance to look at Assignment 5?
A. Not yet
B. I've glanced at it
C. I started reading it but didn't finish
D. I read it all but haven't started working
E. I read it and have started working

Text espertus to 22333 if the
URL isn't working for you.
Introducing A5: Designing Services for Your Team (Individual Assignment)
A4's RecipeService bundled everything into one interface—scaling, conversion, import, search.
That was intentionally problematic. A5 asks you to fix it by designing services aligned
with actors:
| Actor | A5 Service Responsibility | Group Project GUI Component |
|---|---|---|
| Librarian | Collections, import, search | Library View, Import Interface, Search |
| Cook | Step-by-step navigation | Recipe Details/Editor |
| Planner | Shopping lists, scaling, export | (Feature Buffet options) |
You are required to use the first service boundary heuristic and at least one of the other heuristics:
- Actor: Things used by different actors should be separate.
- Rate of Change: Things that change at different speeds should be separate.
- Interface Segregation: Clients that need different things should get different interfaces.
- Testability: Things that need independent testing should be separable.
In-Class Exercise: LibTrack
Read Assignment 5 Prep Exercise.
Begin thinking about and discussing how many services there should be for patron. Consider:
- rate of change
- interface segregation principle
- testability
Consider Repositories Used and Rate of Change
| Command | Description | Repositories |
|---|---|---|
hold <book> 🏎️ | Place a hold on a book for the current patron | BookRepository, HoldRepository |
holds | List the current patron's active holds | BookRepository, HoldRepository |
history🐢 | Show the current patron's borrowing history | LoanRepository, BookRepository |
my account 🐢 | Show the current patron's account details and borrowing status | LoanRepository, BookRepository |
my fines 🏎️ | Show all outstanding fines for the current patron | FineRepository |
pay fine <fine> 🏎️ | Pay an outstanding fine | FineRepository |
Tip: Have AI generate the table for you.
What's the difference between ISP and Actor?
The Actor heuristic says to split things used by different actors.
Interface Segregation says to split things used by different clients.
What's the difference between an Actor and a client?
Different clients used by a single Actor (Patron or Librarian) could be:
- the Holds screen vs. the Fines screen
- a mobile app vs. a web app
One Possible Patron Service Layer
Note: This diagram does not separate interfaces from implementations.
Where does testability fit in?
The single HoldService requires mocking two classes to test isPermittedToPlaceHold().
A separate HoldWaitlistService requires mocking only one class to test
isPermittedToPlaceHold().
(We'd have to add a facade to call the two services.)
ADR-001: Patron Service Boundaries
Context: The client used by the Patron needs to be able to make requests of a service layer that applies business logic to repositories. We were constrained to prioritize the Actor service boundary heuristic.
Decision: We will have these separate service interfaces supporting these commands:
HoldServicehold bookholds[remainder omitted]
We separated HoldService from other services, such as AccountService because of the former's greater rate of change.
Consequences:
- ✅ Decoupling: Changes to hold policy affect only
HoldServiceand its implementations, not other services, such asAccountService. - ⚠️ Testability: We need to mock
BookRepositoryto test the methodisPermittedToPlaceHold(), even though that method does not referenceBookRepository.
Poll: Was the exercise helpful?
A. Yes, I now understand what to do
B. Somewhat
C. I'm still lost
D. I understood what to do already

Text espertus to 22333 if the
URL isn't working for you.
Learning Objectives
After this lecture, you will be able to:
- Explain how component reuse simplifies software development and the role of OSS ecosystems in distributing reusable components
- Describe the role and impact of copyleft licenses on OSS
- Describe tradeoffs that should be considered when adopting a library or framework
- Evaluate a dependency's community health, governance model, and long-term viability
Poll: What does "open source" mean? Is it the same as "free software"?

Text espertus to 22333 if the
URL isn't working for you.
One Line of Code...
Modern software is not written from scratch. Consider adding JSON support to your project:
// build.gradle
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.0'
}
Three JARs for one "dependency." But this is just the beginning...
...But Real Apps Need More
Most apps need Java 8 date/time support and Optional handling. Add two more modules:
Notice the diamond dependencies — multiple paths to jackson-databind. Maven/Gradle resolves these, but version conflicts can cause subtle bugs.
Dependency Hell

Third-Party Dependencies Appear
Add XML and YAML format support — now third-party libraries enter the picture:
Three different organizations now contribute to your project: FasterXML (Jackson), Codehaus (Stax2), and org.yaml (SnakeYAML).
Thousands of Shoulders
Five lines in your build file. Ten JAR files from four organizations.
$ mvn dependency:tree
com.example:jackson-deps:jar:1.0-SNAPSHOT
├── jackson-databind:2.15.0
│ ├── jackson-annotations:2.15.0
│ └── jackson-core:2.15.0
├── jackson-datatype-jsr310:2.15.0
├── jackson-datatype-jdk8:2.15.0
├── jackson-dataformat-xml:2.15.0
│ ├── stax2-api:4.2.1 ← org.codehaus.woodstox
│ └── woodstox-core:6.5.1 ← com.fasterxml.woodstox
└── jackson-dataformat-yaml:2.15.0
└── snakeyaml:2.0 ← org.yaml
What you wrote:
- 5 dependency declarations
- ~20 lines of Java
What you're running:
- 10 JAR files
- 4 different organizations
- Dozens of maintainers
Your JSON/XML/YAML handling stands on the shoulders of developers you've never met, at organizations you may not have heard of.
Infrastructure Code Gravitates Toward Open Source
Your competitive advantage isn't your JSON parser — it's your recommendation algorithm, your UX, your content.
| Layer | Examples | Who Builds It |
|---|---|---|
| Differentiation | Recommendation algorithms, UX, business logic | You (proprietary) |
| Infrastructure | JSON parsing, web servers, encryption, databases | Industry (open source) |
Why would Netflix, Spotify, and Airbnb each employ engineers to independently build the same JSON parser? It makes far more sense to:
- Share the cost of development across the industry
- Benefit from bug fixes and security patches contributed by everyone
- Focus proprietary effort on what actually differentiates your product
The Cathedral and the Bazaar

Eric Raymond on the Cathedral and the Bazaar

The Ecosystem: Package Registries
Open source ecosystems depend on package registries to distribute reusable components:
| Registry | Ecosystem | Examples |
|---|---|---|
| Maven Central | Java/JVM | JUnit, Spring, Jackson |
| npm | JavaScript | React, Express, lodash |
| PyPI | Python | pandas, tensorflow, requests |
| crates.io | Rust | serde, tokio |
| NuGet | .NET | Newtonsoft.Json, Entity Framework |
These registries make it trivial to declare a dependency and have it automatically downloaded — along with all of its transitive dependencies.
Semantic Versioning Encodes Promises
Libraries evolve. Semantic Versioning (SemVer) encodes compatibility promises in version numbers:
MAJOR . MINOR . PATCH
2 . 15 . 0
| Change | Example | Meaning | Safe to Update? |
|---|---|---|---|
| PATCH | 2.15.0 → 2.15.1 | Bug fixes only | ✅ Yes |
| MINOR | 2.15.0 → 2.16.0 | New features, backwards compatible | ✅ Usually |
| MAJOR | 2.15.0 → 3.0.0 | Breaking changes | ⚠️ Review needed |
// Exact version — reproducible but requires manual updates
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.0'
// Any 2.x version — automatic patches but risk of breakage
implementation 'com.fasterxml.jackson.core:jackson-databind:2.+'
The Double-Edged Sword of Dependency
Benefits
- Speed: Don't reinvent the wheel; use battle-tested solutions
- Quality: Popular libraries debugged by millions of users
- Security: Vulnerabilities found and patched quickly (when maintained)
Risks
- Supply chain attacks: Compromised dependency compromises your app
- Abandonment: What happens when a maintainer stops updating?
- License compatibility: Can you legally use this code?
We'll explore the risks — licensing and evaluation — in the rest of this lecture.
Every Line of Code Is Copyrighted by Default
To understand open source licensing, we first need to understand copyright.
Copyright is automatic. The moment you write code, you own exclusive rights to:
- Copy the work
- Modify it (create "derivative works")
- Distribute copies to others
- Display or perform it publicly
Key insight: A GitHub repo with no LICENSE file means "all rights reserved."
You legally cannot use it — even if the author clearly intended to share it.
From BSD to GPL: A Values Fork
The two licensing philosophies grew from the same code lineage — but diverged on a fundamental question about freedom.
| Year | Event | Philosophy |
|---|---|---|
| 1969 | Bell Labs shares Unix freely (AT&T consent decree prevents selling it) | Accidental openness |
| 1977 | Berkeley builds on Unix, creates BSD license: "Do whatever you want, just credit us" | Maximum individual freedom |
| 1983 | Stallman sees companies closing BSD-derived source code. Launches GNU and GPL: "Share alike, forever" | Protect the commons |
Both philosophies shaped the modern world:
| BSD lineage (permissive) | GPL lineage (copyleft) |
|---|---|
| FreeBSD → macOS, iOS | GNU/Linux → Android, Cloud |
| Companies took the code and closed it — as intended | Companies must share kernel changes — as intended |
The irony: BSD's freedom enabled companies to close the source — which is exactly what motivated Stallman to create a license that prevented it. Same code heritage, fundamentally different values.
Two Philosophies: Maximize Adoption vs. Protect the Commons

Eric Raymond on Open Source and Free Software

Richard Stallman (RMS) on Open Source and Free Software
![[The first panel has the second panel inside it. It also has a slightly light gray background color. Just above the inlaid second panel is Richard Stallman lying in his bed sleeping, the bottom part at the foot of the bed hidden behind the second panel below. Below his bed under his head lies a katana sword in its sheath, and another one hangs in its sheath behind the end of the bed. Two ninjas with swords and black cloths around their heads jump through the skylight, smashing it so glass scatters around them. Each of them is hanging one-handed from the same rope coming down from the skylight. The rope ends just above the inlaid frame below. The two ninjas shout at Richard Stallman, from four speech bubbles that have pointy ends to indicate how the two alternately speak. (These bubbles are white, not gray.)]
Richard Stallman: Zzzz
Top Ninja: Richard Stallman! Your viral open source licenses have grown too powerful.
Bottom Ninja: The GPL must be stopped.
Top Ninja: At the source.
Bottom Ninja: You.
[In the second inlaid panel (with normal white background), Richard Stallman wakes up immediately, and while sitting up in bed, he pulls out both his katana swords from their sheaths, leaving the sheaths under and behind the bed. One hand is up in the air with the sword from behind the bed, and the other is still pointing down with the swords from below the bed. Lines indicate the fast movement of the swords. His three speech bubbles are like those of the ninjas, the last two even breaking the panel entering into the large first panel.]
Katana swords: Shing! Shing!
Richard Stallman: Hah! Microsoft lackeys! So it has come to this!
Richard Stallman: A night of blood I've long awaited. But be this my death or yours, free software will carry on! For a GNU dawn! For freedom!
Richard Stallman: ...Hey, where are you going?
[An outside scene at night with black sky. Richard Stallman's gray house can be seen with the broken white skylight on the roof. The ninjas are jumping out of a window at ground height while taking off their ninja cloth around their heads, holding them in their hand, thus revealing that they both look like Cueball. The first one is already on the grassy ground beneath the window, his sword pointing down and to the left; the other just jumps from the window pane, his sword pointing up and to the right. Again, they have speech bubbles like before. It is not possible to tell which of the two ninjas from before is first out the window.]
Ninja in window: Man, you're right, that never gets old.
Ninja on the grass: Let's do Eric S. Raymond next.
Ninja in window: Or Linus Torvalds. I hear he sleeps with nunchucks.](/cs3100-public-resources/img/lectures/web/l23-rms-xkcd.png)
https://youtu.be/Ag1AKIl_2GM?si=21E_IZFYRm_flMBY&t=525
Image: 'Open Source', xkcd.com/225, Randall Munroe, CC BY-NC 2.5
Permissive vs. Copyleft: Quick Reference
| Question | Permissive (MIT, Apache, BSD) | Copyleft (GPL, LGPL, AGPL) |
|---|---|---|
| Can I use it in proprietary software? | Yes | Usually requires open-sourcing your code |
| Must I share my modifications? | No | Yes, if you distribute |
| Philosophy | Maximize adoption | Protect the commons |
| Popular examples | React, Jackson, Spring | Linux kernel, GCC, WordPress |
Most popular libraries use permissive licenses: React (MIT), Jackson (Apache 2.0), Spring (Apache 2.0), TensorFlow (Apache 2.0)
GPL powers critical infrastructure: Linux kernel, many Linux utilities (maintained by GNU), forces community participation
Practical Licensing Guidance
For most developers using open source libraries:
- Check the license before adding a dependency. It's usually in a
LICENSEfile or package metadata. - Permissive licenses are low-risk for most commercial projects.
- GPL requires careful attention if you're building proprietary software — consult your legal team.
Licenses as Values: The Unusual Cases

Every Dependency Is a Commitment
Adding a dependency is easy — one line in build.gradle. But every dependency is a commitment.
Before adopting a library or framework, ask yourself:
- Who maintains this, and will they still be maintaining it in two years?
- What happens if I need to switch away from it later?
- Am I comfortable with the license terms?
- How much will this shape the rest of my code?
The last question matters most: A utility library for string formatting has minimal impact — swap it out easily. A web framework influences your entire application structure. Migrating away could mean a rewrite.
Community Health: The Most Important Factor
Before adopting a library, investigate who's behind it and how active they are:
| Indicator | What to Look For | Red Flags |
|---|---|---|
| Recent activity | Last commit? Last release? | No updates in 2+ years |
| Issue responsiveness | Are bugs acknowledged? PRs reviewed? | 500 ignored issues |
| Bus factor | How many core maintainers? | Single maintainer |
| Documentation | Up-to-date? Comprehensive? | Outdated or missing docs |
Sobering reality: OpenSSL — securing most of the internet — was maintained by a handful of volunteers until the Heartbleed vulnerability exposed how underfunded critical infrastructure can be.
Governance Models Shape Long-Term Risk
| Model | Examples | Pros | Cons |
|---|---|---|---|
| Corporate-backed | Chromium (Google), React (Meta), TensorFlow (Google) | Well-funded, full-time devs | Priorities may shift; may change license |
| Foundation-governed | Apache projects, Linux Foundation, Python SF | Community governance, stable long-term | May move slower |
| Community/Individual | Many small libraries and utilities | Innovative, responsive | High abandonment risk; may lack security audits |
Watch out for license changes:
- MongoDB: AGPL → Server Side Public License (SSPL)
- HashiCorp: Terraform from MPL → Business Source License (BSL)
- Redis: BSD → dual-license with SSPL
When Governance Fails: The Fork
| Original | Fork | What Happened |
|---|---|---|
| MySQL | MariaDB | Oracle acquired Sun (2009). Community worried about stewardship. |
| OpenOffice | LibreOffice | Oracle fired developers (2010). Community forked. LibreOffice won. |
| Terraform | OpenTofu | HashiCorp changed to restrictive license (2023). Linux Foundation hosts the fork. |
The code can live on — but the disruption is painful for everyone. Forks are possible because the source is open. The only thing original creators keep is the trademark.
The Human Side of Open Source
Behind every dependency in your build.gradle is a person — often unpaid, often alone.
The reality of OSS maintenance:
- Most critical infrastructure runs on volunteer labor
- OpenSSL (secures the internet): 2 maintainers pre-Heartbleed
- Burnout is the #1 cause of project abandonment
L22's bus factor — at ecosystem scale:
- Your team has 4 people. What if one leaves?
- SnakeYAML has one maintainer. What if they leave?
- The consequences ripple across thousands of projects
- This isn't a team problem — it's an industry problem
The paradox: We trust billion-dollar systems to maintainers we've never met, often without paying them. The same HRT principles from L22 apply here — except the "team" is the entire open source community.
A Well-Maintained Library Beats DIY for Security
Is it safer to use a popular library or write your own? Almost always use the library — if it's well-maintained.
Why well-maintained libraries win:
- Battle-tested by thousands of users
- Security researchers scrutinize popular projects
- Vulnerabilities get reported and patched
- You benefit from specialists' expertise
When dependencies introduce risk:
- Every dependency is an attack surface
- Transitive dependencies multiply the risk
- Unmaintained dependencies don't get patches
- You're trusting code you've never read
The key insight: You're unlikely to out-engineer the Jackson team at JSON parsing, or the Spring Security team at authentication. But you DO need to keep your dependencies updated.
Supply Chain Attacks: When Dependencies Become Vectors
An attacker compromises a package deep in the dependency tree. Your app pulls it in transitively — you never knew it existed. Now the attacker's code runs in your application.
| Incident | What Happened | Impact |
|---|---|---|
| left-pad (2016) | Developer unpublished an 11-line npm package | Thousands of builds broke — Facebook, Spotify, others |
| Log4Shell (2021) | Critical remote code execution in Log4j | Millions of apps affected; months to remediate |
A chain is only as strong as its weakest link. The risks compound when you adopt a library and never update it, the library is abandoned, or a malicious actor compromises it.
The Internet Was Weeks Away from Disaster and No One Knew (Veritasium)

Being a Good OSS Citizen
You're not just a consumer of open source — you're a participant. L22's HRT principles apply to the global community, not just your team.
Apply L22's practices to OSS:
- File good issues — you learned this in L22. Same template: steps to reproduce, expected vs. actual, environment.
- Look for "good first issue" labels — many projects tag beginner-friendly tasks. This is your on-ramp.
- Contribute docs, not just code — the most impactful first contribution is often a typo fix or a clearer example
- Respect maintainer time — they owe you nothing. A polite, well-researched issue gets answered; "fix this!" gets ignored.
Apply L22's HRT:
- Humility: You're new to their codebase. Ask before assuming.
- Respect: Read the CONTRIBUTING.md before submitting a PR. Follow their conventions, not yours.
- Trust: If a maintainer closes your issue, assume good faith. Ask why, don't demand.
Start now: Every one of you uses open source daily. You can contribute today — report a bug, improve docs, answer a question on Stack Overflow. You don't need permission to participate in the bazaar.
Architectural Decisions About Dependencies
The same heuristics from L18 apply to dependency decisions:
| L18 Heuristic | Applied to Dependencies |
|---|---|
| Rate of Change | Does this library's release cadence match your needs? Will breaking changes disrupt you? |
| Actor / Ownership | Who maintains this? One person? A foundation? A company that might change the license? |
| Interface Segregation | Does the library do ONE thing well, or is it a bloated framework you'll never escape? |
| Testability | Can you mock/stub this dependency? Or does it couple you to infrastructure? |
The key insight: Adopting a dependency is an architectural decision. It affects coupling, changeability, testability, and security — the same qualities we've been optimizing for all semester.
Bonus cartoon
