Java 8 Compatibility Rules for NeqSim
All NeqSim Java code — including test classes in src/test/java/ — MUST compile with Java 8. The CI build will FAIL if you use Java 9+ features.
Forbidden Java 9+ Features
| Forbidden | Java 8 Alternative |
|---|---|
var x = ... |
Explicit type: String x = ..., Map<String, Object> map = ... |
List.of(a, b) |
Arrays.asList(a, b) or Collections.singletonList(a) |
Set.of(a, b) |
new HashSet<>(Arrays.asList(a, b)) |
Map.of(k, v) |
Collections.singletonMap(k, v) or new HashMap<>() |
"str".repeat(n) |
StringUtils.repeat("str", n) (Apache Commons) |
str.isBlank() |
str.trim().isEmpty() |
str.strip() |
str.trim() |
str.lines() |
str.split("\\R") or BufferedReader |
Optional.isEmpty() |
!optional.isPresent() |
Text blocks """...""" |
Regular strings with \n |
| Records | Regular class with fields, constructor, getters |
Pattern matching instanceof |
Traditional instanceof + cast |
Stream.toList() |
.collect(Collectors.toList()) |
Common var Replacements
// WRONG (Java 10+):
var map = someMethod.toMap();
var list = getItems();
var result = calculate();
// CORRECT (Java 8):
Map<String, Object> map = someMethod.toMap();
List<String> list = getItems();
CalculationResult result = calculate();
Required Import for String Repeat
import org.apache.commons.lang3.StringUtils;
// Usage: StringUtils.repeat("=", 70)
Code Formatting (Spotless) — MANDATORY
AI-generated Java is NOT auto-formatted. After creating or editing ANY .java
file, reformat it before committing — do not rely on local pre-commit hooks
being installed:
./mvnw spotless:apply # reformats Java to the project style (Eclipse profile)
./mvnw spotless:check # verifies formatting — this is what CI runs
- Formatter profile:
.config/neqsim_formatter.xml(configured inpom.xml), applied tosrc/main/javaandsrc/test/java. - CI runs
./mvnw spotless:checkand FAILS the build on any unformatted file. - Run
spotless:apply, thengit addthe reformatted files, then commit. - NEVER bypass the gate with
git commit --no-verify.
API Verification (MANDATORY)
Before using any NeqSim class in code or examples:
- Search for the class:
file_search("**/ClassName.java") - Read constructor and method signatures from the actual source
- Use only methods that actually exist with correct parameter types
- Do NOT assume convenience overloads — check first
Common API mistakes:
- Assuming
getXxx95()when actual isgetXxx(int percentile) - Assuming 1-arg constructors when 2+ args are required
- Calling methods on wrong class
- Assuming
calculate()when actual iscalculateRisk()orrun()
JavaDoc Requirements
All classes and methods (public, protected, AND private) require complete JavaDoc:
- Class-level: description,
@author,@version - Method-level: description,
@paramfor every parameter,@returnfor non-void,@throwsfor each exception - HTML5 compatible: use
<caption>in tables (nosummaryattribute) - No
@seewith plain text — only valid Java references - No lambda arrows (
->) in JavaDoc code examples
Build Commands
./mvnw install # full build
./mvnw test -Dtest=ClassName # single test class
./mvnw test -Dtest=ClassName#methodName # single method
./mvnw checkstyle:check spotbugs:check pmd:check # static analysis
./mvnw javadoc:javadoc # verify JavaDoc
Serialization — SE_BAD_FIELD Rule (MANDATORY)
SpotBugs enforces that all instance fields in Serializable classes are either
serializable themselves or marked transient. This applies to any class extending
ProcessEquipmentBaseClass, MeasurementDeviceBaseClass, MechanicalDesign,
thermo phase classes, or any other Serializable class.
When to use transient
Mark a field transient when its type does NOT implement Serializable:
- Functional interfaces:
Function,BiConsumer,Consumer,Supplier - JDBC:
Connection,Statement,ResultSet - Threads:
Thread,ExecutorService - Apache Commons Math:
BicubicInterpolator,BicubicInterpolatingFunction,LinearInterpolator - Inner classes that don't implement
Serializable(e.g.,NetworkNode,GibbsComponent) - External library types not designed for serialization
Correct modifier order
// private fields
private transient MyType field;
private final transient List<NonSerializableInner> items = new ArrayList<>();
// package-private fields
transient SomeType field;
Verify with SpotBugs
./mvnw spotbugs:check 2>&1 | Select-String "SE_BAD_FIELD" # should return empty