Class GuardrailEngine
static state,
no component in a static field, no JVM exit.
This is the implementation, not the migrator's entry point. A migrated app calls
com.vaadin.swingbridge.migration.guardrails.MigrationGuardrails, a facade over this class in a test-scope
artifact, so the migrator imports one SB-Emulators type and no com.tngtech.*
(M1D_guardrails_artifact). The engine lives here because StaticSweep asks the same
immutability question for the opposite purpose — a worklist during the migration rather than a gate
after it — and answering it twice is what makes a rule drift
(M1D_static_sweep_tool § Q_one_rule_engine). The shared half is ImmutableTypes.
The two terminals do not collapse into each other. violations() returns the
report and judges nothing, which is what a `main` printing a worklist needs — mid-sweep a non-empty
list is the expected state, not a failure. The facade's run() throws on the same list,
which is what makes the sweep stay done once a static field is added months later.
This class never depends on :emulators, :surrogates or anything Vaadin: the
component types are matched by name, so a migrated app's UI-free service module can install
the gate without a Vaadin dependency flipping its Step-0 classification, and there the names
resolve to nothing and the rule trivially passes.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionallowSystemExitIn(String... fullyQualifiedClassNames) Permits JVM exit anywhere in the named classes.PermitsSystem.exitin the body of apublic static void main(String[])and nowhere else.voidvoidvoidstatic GuardrailEngineforImportedClasses(com.tngtech.archunit.core.domain.JavaClasses classes) Runs the rules over classes the caller imported, bypassing the package scan — and with itDO_NOT_INCLUDE_TESTS, which would skip a fixture living in test output.Every violation of all three rules, each entry a rendered failure report.
-
Constructor Details
-
GuardrailEngine
- Parameters:
rootPackages- the app's own roots. Leaving one out makes the rules pass by not looking at it; naming one wider than you own sweeps somebody else's classes into your result.
-
-
Method Details
-
forImportedClasses
public static GuardrailEngine forImportedClasses(com.tngtech.archunit.core.domain.JavaClasses classes) Runs the rules over classes the caller imported, bypassing the package scan — and with itDO_NOT_INCLUDE_TESTS, which would skip a fixture living in test output. -
allowSystemExitInMainMethods
PermitsSystem.exitin the body of apublic static void main(String[])and nowhere else. A lambda insidemainis not covered — deliberately, sinceinvokeLater(() -> … System.exit(0))is exactly the UI-reachable exit the gate exists to catch. -
allowSystemExitIn
Permits JVM exit anywhere in the named classes.- Parameters:
fullyQualifiedClassNames- matched exactly —"com.myapp.Main"does not covercom.myapp.Main$1, so an anonymous class stays gated
-
violations
Every violation of all three rules, each entry a rendered failure report.Never short-circuits: stopping at the first would serialise the worklist into fix-statics, re-run, now discover the
System.exit.- Returns:
- empty when the app passes. **Judges nothing** — a caller printing a worklist wants the list, a caller gating a build throws on it.
- Throws:
AssertionError- only if the roots resolved no classes at all, which is a mistyped root rather than a finding
-
checkStaticState
public void checkStaticState()- Throws:
AssertionError- if astaticfield is neither provably immutable nor allowlisted
-
checkStaticComponents
public void checkStaticComponents()- Throws:
AssertionError- if astaticfield's type is a component
-
checkJvmExit
public void checkJvmExit()- Throws:
AssertionError- if any code unit terminates the JVM outside the permitted places
-