Thank you for your interest in contributing to jcommons! This document provides guidelines and instructions for contributing to this project.
- Code of Conduct
- Getting Started
- Development Setup
- Making Changes
- Coding Standards
- Testing Requirements
- Submitting Changes
- Release Process
This project adheres to the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.
When creating a new issue, please use the appropriate issue template:
- Bug Report - Report unexpected behavior or errors
- Feature Request - Suggest new features or enhancements
- v2.0 Migration Feedback - Feedback on deprecated method migrations
- Security Vulnerability - DO NOT USE - Report security issues privately via Security Advisories
Note: Blank issues are disabled. All issues must use a template.
An issue is actionable only when it satisfies:
- Specify version:
mainbranch vs latest stable (v1.31) - Reproducible on specified version
- Java 17+ confirmed
- Apache CXF 4.0+ confirmed (if using SoapUtil)
- Relevant dependency versions listed
- Grounded in
org.flossware.jcommonssource code - Related to Solenopsis framework interaction (if applicable)
- Not an external dependency issue
- Includes minimal reproduction test case
- Maintains 93% coverage baseline
- Links to branch/PR with failing test
- Contributions governed by GPL v3.0
- Acknowledged in template or PR
Issues not meeting the Definition of Done will be labeled:
needs-info- Missing required informationneeds-reproduction- Missing test caseneeds-version- Version not specifiedneeds-env- Environment details missing
Once all requirements are met, the issue will be labeled actionable.
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/jcommons.git cd jcommons - Add upstream remote:
git remote add upstream https://github.com/FlossWare/jcommons.git
- Create a feature branch:
git checkout -b feature/your-feature-name
- Java 17+ (required)
- Maven 3.6.3+ (required)
- Git (required)
# Clean build with all quality checks
mvn clean verify
# Run tests only
mvn test
# Run specific test
mvn test -Dtest=StringUtilTest
# Generate coverage report
mvn clean test
# View report at: target/site/jacoco/index.htmlThe build runs multiple quality checks automatically:
- JaCoCo - Code coverage (minimum: 93% instruction, 86% branch, 93% line)
- SpotBugs - Static analysis for bugs
- PMD - Code quality analysis
- Checkstyle - Code style validation (Google Java Style)
- Maven Enforcer - Dependency and version validation
- OWASP Dependency Check - Security vulnerability scanning
All checks must pass for the build to succeed.
For deep quality validation, you can run PIT mutation testing:
# Run PIT mutation testing (takes 5-10 minutes)
mvn org.pitest:pitest-maven:mutationCoverage
# View report
open target/pit-reports/index.html
# Or: xdg-open target/pit-reports/index.html (Linux)What is Mutation Testing?
Mutation testing evaluates test quality by:
- Introducing small code changes (mutations)
- Re-running tests
- Checking if tests catch the mutations
Target: 80% mutation coverage
When to Use:
- Before major releases
- When refactoring complex logic
- To verify test effectiveness
- Not required for every commit (use
mvn verifyinstead)
To generate a unified quality dashboard:
# Generate comprehensive site with all reports
mvn clean verify site
# View site
open target/site/index.htmlThe site includes:
- Code coverage (JaCoCo)
- Static analysis (SpotBugs, PMD, Checkstyle)
- JavaDoc
- Dependency reports
- All quality metrics in one place
Use descriptive branch names with prefixes:
feature/- New featuresfix/- Bug fixesdocs/- Documentation updatesrefactor/- Code refactoringtest/- Test improvements
Examples:
feature/add-xml-utilitiesfix/null-pointer-in-string-utildocs/update-readme-examples
Follow the Conventional Commits format:
<type>: <subject>
<body>
<footer>
Types:
feat:- New featurefix:- Bug fixdocs:- Documentation onlystyle:- Code style changes (formatting, no logic change)refactor:- Code refactoringtest:- Adding or updating testschore:- Maintenance tasks
Example:
fix: Correct null handling in StringUtil.requireNonBlank
The method was not properly handling null inputs, causing
NullPointerException instead of IllegalArgumentException.
Added comprehensive tests for null and empty string cases.
Fixes #123
- Write code following our Coding Standards
- Add tests for all new functionality
- Update documentation (JavaDoc, README, CHANGELOG)
- Run quality checks:
mvn clean verify - Ensure 100% test coverage for new code
- Java 17 language features are allowed
- Follow Google Java Style Guide (enforced by Checkstyle)
- Use meaningful names for variables, methods, and classes
- Keep methods focused - one responsibility per method
- Prefer immutability where possible
- Use final for parameters and local variables when practical
// Classes: PascalCase
public class StringUtil { }
// Interfaces: PascalCase
public interface Stringifiable { }
// Methods and variables: camelCase
public void parseString() { }
private String userName;
// Constants: UPPER_CASE_WITH_UNDERSCORES
private static final String DEFAULT_SEPARATOR = "";
private static final Logger LOGGER = Logger.getLogger(...);
// Packages: lowercase
package org.flossware.jcommons.util;Use consistent error message phrasing:
// ✅ Good
Objects.requireNonNull(obj, "Object must not be null");
StringUtil.requireNonBlank(str, "String must not be null or blank");
// ❌ Avoid
Objects.requireNonNull(obj, "Cannot have a null object!");
Objects.requireNonNull(obj, "Must have an object!");All public APIs require JavaDoc:
/**
* Validates that a string is not null, empty, or whitespace-only.
*
* @param string the string to validate
* @param message the error message if validation fails
* @return the validated string
* @throws IllegalArgumentException if the string is blank
*/
public static String requireNonBlank(String string, String message) {
// implementation
}- Use
java.util.logging.Logger(not SLF4J or Logback) - Static logger field:
private static final Logger LOGGER - Appropriate levels: SEVERE (errors), WARNING (warnings), INFO (informational), FINE/FINER/FINEST (debug)
- Use parameterized logging:
private static final Logger LOGGER = Logger.getLogger(ClassName.class.getName());
// ✅ Good
LOGGER.log(Level.INFO, "Processing file: {0}", fileName);
// ❌ Avoid
LOGGER.log(Level.INFO, "Processing file: " + fileName);- Minimum coverage: 93% instruction, 86% branch, 93% line (enforced by JaCoCo)
- Goal: 100% coverage for new code
- Current status: 100% instruction, 96% branch, 100% method, 100% line, 100% class
class StringUtilTest {
@Test
void testRequireNonBlank_withValidString() {
String result = StringUtil.requireNonBlank("hello");
assertEquals("hello", result);
}
@Test
void testRequireNonBlank_withNull() {
assertThrows(IllegalArgumentException.class,
() -> StringUtil.requireNonBlank(null));
}
@Test
void testRequireNonBlank_withEmptyString() {
assertThrows(IllegalArgumentException.class,
() -> StringUtil.requireNonBlank(""));
}
}- Use descriptive names:
test<Method>_<Condition> - Examples:
testRequireNonBlank_withValidStringtestFromString_withNullInputtestSetHeader_throwsExceptionForNullService
- Happy path - Normal, expected usage
- Edge cases - Null, empty, boundary values
- Error cases - Invalid input, exception handling
- Security features - ObjectInputFilter, path validation
- Integration - Component interactions
-
Sync with upstream:
git fetch upstream git rebase upstream/main
-
Run full build:
mvn clean verify
-
Ensure all tests pass:
mvn test # Should show: Tests run: 277, Failures: 0, Errors: 0, Skipped: 0
-
Check code coverage:
mvn clean test open target/site/jacoco/index.html
-
Push to your fork:
git push origin feature/your-feature-name
-
Create Pull Request on GitHub:
- Use a clear, descriptive title
- Reference related issues: "Fixes #123"
- Describe what changed and why
- Include test evidence (coverage, test counts)
-
PR Template (include in description):
## Description Brief description of changes ## Related Issues Fixes #123 ## Changes Made - Added X feature - Fixed Y bug - Updated Z documentation ## Testing - All 277 tests pass - Coverage: 100% instruction, 96% branch - Added 5 new tests for feature X ## Checklist - [ ] Tests added/updated - [ ] JavaDoc updated - [ ] README updated (if needed) - [ ] CHANGELOG updated - [ ] All quality checks pass
-
Address review feedback
-
Wait for approval from maintainers
-
Squash and merge (maintainers will handle)
Releases are automated via GitHub Actions:
- Development on
mainbranch - CI/CD runs on every push:
- Runs all tests and quality checks
- Generates JavaDoc
- Runs OWASP dependency check
- Deploys to packagecloud.io
- Creates git tag
- Versioning is automatic (patch bump on each merge)
- CHANGELOG should be updated manually
- v1.x - Current stable branch
- v2.0 - Future major release (breaking changes)
See CHANGELOG.md for deprecation schedule.
- Issues: https://github.com/FlossWare/jcommons/issues
- Discussions: Use GitHub Discussions for questions
- Security: See SECURITY.md for vulnerability reporting
By contributing, you agree that your contributions will be licensed under the GNU General Public License v3.0.
Thank you for contributing to jcommons! 🎉