
Case Study
1. Introduction and Motivation
Scriptorium is primarily a powerful command-line application (CLI) for managing a library. The project demonstrates how to create a user experience with modern Java libraries (Picocli, JLine3) that doesn't have to hide behind graphical interfaces. Additionally, it shows how a clean architecture ("Clean Architecture") enables the same application core to optionally be provided as a REST API (via Javalin).
2. Problem Statement and Goals
Problem: CLI tools are often clunky, don't support interactive input, and are difficult to extend. On the other hand, "enterprise" web applications are often over-engineered for local use cases.
Goals:
- Interactive Shell: Starting the application in a REPL mode (Read-Eval-Print-Loop) with command history and autocomplete.
- Modularity: Separation of input/output (CLI) and business logic (Core) to easily add a web interface later.
- Lightweight: Avoiding heavy frameworks like Spring Boot in favor of focused libraries (Javalin, Picocli).
- Transparency: Using JDBC instead of Hibernate to maintain full control over SQL queries.
3. System Architecture and Design
Architecture Overview: The core of the application is independent of the presentation layer. This enabled the seamless integration of the API server as a mere "feature" of the CLI.
- Interactive CLI (
org.scriptorium.application.Main): Uses JLine3 for the REPL. If no arguments are passed, the interactive shell starts (scriptorium>). - Command Parsing (
org.scriptorium.cli): Picocli defines the command structure (book import,server start) and converts inputs into method calls. - API Server (
org.scriptorium.api): An integrated Javalin server that can be started via the CLI commandserver start. It uses the same services as the CLI. - Data Layer: Pure JDBC and SQLite provide persistent data storage without installation overhead.
Dependency Injection:
A custom DependencyFactory acts as the Composition Root. It instantiates all repositories and services at startup and injects them into the Picocli commands. This avoids "magic" and makes the application startup extremely fast.
4. Implementation Highlights
Import & Resilience:
The BookImportService uses Jackson to load books from the Open Library API. Since the API can deliver unpredictable data structures (Array vs. Single Object), the service implements intelligent fallback strategies during JSON parsing.
Hybrid Mode:
The application is a hybrid solution. It can be used as a pure admin tool (scriptorium book list) or started as a server to provide data for other applications (e.g., a frontend) (GET /api/books).
5. Results and Outlook
Achieved Goals: Scriptorium feels "snappy." The interactive shell is fun to use, and the ability to spawn a web server on demand makes the tool extremely flexible.
Next Steps:
- TUI Dashboard: Extending the CLI with a text-based dashboard (using
lanterna) for statistics. - Native Image: Thanks to the chosen libraries, compilation with GraalVM is possible to create a standalone binary without JVM dependency.
6. Personal Growth and Lessons Learned
SQL & JDBC: Avoiding ORM frameworks sharpened my understanding of relational databases and transaction management. I had to learn how to map ResultSets efficiently and manually avoid N+1 problems.
CLI UX: I learned that a good CLI is more than just parsing arguments. A consistent command structure, good help texts, and an interactive shell significantly increase the tool's acceptance.