Mastering Git, Maven, and Java Build Automation
README and Markdown Essentials
A README is a simple text file that introduces and explains a software project, including how to install, use, and collaborate. You should begin this documentation before you start the project, placing it at the root folder (the top level of the project). Markdown is a lightweight text-to-HTML markup language that is easy to read and write, and it is supported by many tools.
Version Control Systems (VCS)
- Local: Everything is saved on a personal computer. It is fast, simple, and offers full control, but provides no collaboration and carries a high risk of data loss.
- Centralized: One central server holds the project. Every developer can read and write, but they maintain only the current version in their working directory. It offers easy administration and access control but has a single point of failure, is slower, and has limited offline capability.
- Distributed (Git): Every developer downloads a full copy of the entire project history to their own computer. They can work offline, create, sync, and collaborate. It is secure and flexible but complex, requires larger storage, and involves more administrative work.
Git vs. Older VCS
Older Version Control Systems only save the changes made, while Git saves each new version of a file in its entirety with a unique ID (SHA-1 hash). This makes data manipulation nearly impossible.
Stages of Files in Git
- Working Directory (Modified): This is where you are currently editing your files.
- Staging Area (Staged): Files are ready to create a new version. You save them here via
git add [files]. You are preparing these files to be saved. - Repository (Committed): After running
git commit -m "…", the snapshot is now permanently saved in your project history.
Branching and Conflicts
Branching allows you to experiment and work separately without changing the main version. It is used for testing ideas for improvement, working on features, or fixing bugs. Conflicts occur when merging branches that have competing commits. A Three-Way Merge looks at both branches and the original version, then modifies the files with conflict dividers which you must resolve manually.
Build Automation and JAR Files
Build automation takes all your raw materials (code, images, libraries) and automatically assembles them into a finished, ready-to-use product. A JAR is a ZIP file specifically for Java. It bundles all compiled code (.class files) and resources (images and text) into one single, easy-to-share file for efficient file management. To make a JAR file “runnable,” a special text file inside called the Manifest tells the computer exactly which file contains the Main-Class.
The CRISP Automated Build Process
- Complete: It does everything from start to finish without human intervention.
- Repeatable: It gives the exact same result every single time you run it.
- Informative: It provides clear and detailed feedback.
- Schedulable: You can set it up to run at specific times.
- Portable: It works on any computer.
The .gitignore file prevents useless or sensitive files from being committed, such as passwords, sensitive configurations, personal IDE settings, and .class files.
Maven: Project Management and Lifecycle
Maven is a tool for managing the build lifecycle in Java projects. It makes the build process easy by using “convention over configuration” and providing guidelines for development best practices. It uses a uniform build system to ensure that upgrading to newer versions or migrating to new features is as smooth as possible. It is controlled by one central configuration file: pom.xml.
The pom.xml File Structure
- Basic Info: Includes groupId (project group/reverse domain-name notation), artifactId (the final name of the project), and version.
- Packaging: Defines what kind of file should be built (e.g., a JAR).
- Dependencies: A list of external libraries the project needs to work.
- Build Settings & Profiles: Specific instructions for how the code should be built for different environments.
Maven Repositories
- Local Repo: A folder on your own computer where Maven caches previous downloads.
- Central Repo: A massive public database managed by the Maven community containing standard, public libraries.
- Remote Repo: A private, custom server set up by a specific company to host their own internal code.
The Maven Build Lifecycle
- Validate: Checks if the project structure is correct and all information is present.
- Compile: Converts raw
.javasource code into compiled.classbytecode in a target directory. - Test: Runs automated unit tests (JUnit) against the compiled code.
- Package: Bundles the compiled code into the final distributable format (JAR file).
- Verify / Install / Deploy: Runs final quality checks, installs the package into your local repository, and uploads it to a remote server.
The command mvn clean deletes the target directory, wiping out all previously built files so you can start fresh.
Software Quality and Testing
The Infection Chain
- Error (Mistake): A human action that produces an incorrect result (e.g., a syntax error).
- Defect (Fault/Bug): An imperfection or deficiency in a work product caused by an error.
- Failure: The actual event where the software system crashes or fails to perform its function because the defect was executed.
Categorization and Lifecycle
Code is categorized into manual vs. generated code, source code vs. configuration files, and production code vs. test code. The Development Lifecycle involves dependencies, compiling sources, compiling test sources, running tests, creating artifacts, and finally deploying or informing. The Build Process combines configuration, source code, test code, libraries, and documentation into a new artifact. Automation handles compiling source code, running tests, packaging artifacts, managing dependencies, deploying applications, and generating reports.
Documentation Types
- Tutorials: Learning-oriented, step-by-step lessons for beginners (e.g., teaching a child to cook).
- How-To Guides: Goal-oriented (e.g., a recipe).
- Reference Guides: Information-oriented, technical descriptions (e.g., an ingredient encyclopedia).
- Explanations: Understanding-oriented, focusing on “why” (e.g., a discussion of cooking in the context of history).
Git Workflows and Debugging
- Pull Requests: A developer notifies team members that a feature is complete.
- Centralized Workflow: All developers use a single central repo. They pull code, make changes locally, and push back up.
- Feature Branch Workflow: All development is realized in dedicated branches. The main branch should never contain broken code.
- Gitflow Workflow: The main branch stores official releases; ongoing development happens in a separate develop branch.
- Forking Workflow: Common in Open Source. Developers push to their personal fork and submit a Pull Request to the official repo.
Debugging involves tracking the problem, reproducing it, automating the process, finding the origin, isolating the defect, correcting the error, and re-running all automated tests.
Testing with JUnit
Levels of Testing
- Unit Tests: Tests the smallest pieces of code (individual methods/functions) in isolation. They are fast and cheap.
- Integration Tests: Tests how different pieces of software (e.g., code and a database) communicate and work together.
- End-to-End Tests: Validates the entire application flow from start to finish.
- UI Tests: Tests the Graphical User Interface (buttons, menus) to ensure correct user interaction.
JUnit Phases and Syntax
JUnit is a Java framework used to run unit tests automatically. The phases are: Setup (prepare the system), Exercise (execute the function), Verify (check results), and Teardown (clean up resources).
@Test: Marks a method as a test.@BeforeEach/@AfterEach: Initialize and release resources per test.@Ignore/@Disabled: Skips the test.- Assertions: Commands like
assertEquals(expected, actual)that check if a condition is true.
Best Practices for Messages and Comments
Good Git Commit Messages: Use a line between the summary and main text. Keep the summary under 50 characters, start with a capital letter, do not use a period, and use the imperative mood. The main text should break at 72 characters and describe what and why, not how.
Code Comments: Do not duplicate the code. Good comments do not excuse unclear code. Comments should dispel confusion, explain unidiomatic code, and provide links to sources or external references. Use // TODO for incomplete implementations. Javadoc is used to document the public API (classes, methods, variables) using tags like @param, @return, and @author to automatically generate HTML documentation.
Maven Site: Automatically generates a complete website documenting your project, combining Javadoc, test results, and project configurations.
Command Reference
Git Commands
git clone: Copy a full existing repository, including every version and history.git add: Moves files to the staging area.git commit -m: Saves changes to the local repository with a descriptive message.git push: Shares latest commits with the remote repository.git pull: Fetches remote data and immediately merges it into local files.git status: Shows differences between staged files, commits, and the working directory.git log: Shows all old versions and commit messages.git branch [name]: Create a new branch.git branch --list: Get a list of all branches.git checkout [name]: Switch to a branch (-bto create and switch).git merge [name]: Combine two independent commit histories.git branch -d [name]: Delete a branch.git commit -a: Shortcut to automatically stage and commit all modified files.git push -u origin [branch]: Uploads local commits and links the branch to the remote.git fetch: Downloads remote branches and commits without merging.git branch -r/-a: Lists remote or all branches.git checkout -- [file]: Revert a file back to the last commit (changes will be lost).git pull origin main --allow-unrelated-histories: Merge unrelated histories.
Java and JAR Commands
javac [file.java] -d [path]: Compiles Java code into bytecode;-dspecifies the storage path.java -cp [path] [package.classname] [args]: Runs a compiled Java class.jar cf [file.jar] [input_files]: Creates a new JAR file.jar cvf [file.jar] -C build/classes: Creates a JAR file as a library.jar cfm MyProgram.jar manifest.txt Main.class: Specifies a manifest and class file.jar cvfm [file.jar] [path] -C build/classes: Creates a runnable JAR file.java -jar [file.jar]: Runs an executable JAR file.
