Skip to content

Install the empty Guice module loader before the suite in openam-scripting and openam-audit-context tests #1187

Closed

Description

@maximthomas

Context

#1186 fixed a class-order dependence in the openam-core-rest tests. InjectorHolder builds its injector once per JVM, from the module loader InjectorConfiguration holds at that moment. A test class that reaches it before another class installs its loader therefore decides which injector every later class gets. The review of #1186 pointed at the same pattern in other modules, where tests install their loader in @BeforeClass or @BeforeMethod rather than before the suite.

Current state

Measured at 5eb929e, with the class order fixed by a TestNG suite XML (-Dsurefire.suiteXmlFiles). No order of a module's own test classes fails today, so the hazard is latent.

  • openam-scripting. The default loader cannot build an injector on this test classpath: No implementation for NotificationBroker was bound, through CoreGuiceModule -> SessionGuiceModule. GroovyValidatorTest, JavaScriptValidatorTest and GroovyAstTransformEscapeTest install an empty loader in their @BeforeMethod setupGuiceModules() override. That happens before GuiceTestCase.setupGuiceModules() first reaches the holder, and none of the other 23 classes touches it.
    • A new class could reach InjectorHolder without a hook, for example through SupportedScriptingLanguage.getScriptValidator(), ScriptEngineConfigurator.updateConfig or ScriptingSetupListener. If it runs first, all three classes fail in setupGuiceModules with NoClassDefFoundError: Could not initialize class org.forgerock.guice.core.InjectorHolder.
    • Reproduced with a scratch class of that kind.
  • openam-audit/openam-audit-context. AuditContextFilterTest is the only test class, and it installs its loader in @BeforeClass. Here the default loader builds an empty injector.
    • A new unhooked class that runs first leaves AuditContextFilterTest with that injector, and both of its tests fail with No implementation for TransactionIdConfiguration was bound.
    • Reproduced with a scratch class.
  • openam-datastore. Nothing to do. No test reaches InjectorHolder, so nothing reads the loader IdRepoTestBase installs in @BeforeClass.

Proposed change

Test code only. In openam-scripting and openam-audit-context, install the empty loader from @BeforeSuite(alwaysRun = true), as IdentityResourceNotificationTest does in openam-core-rest after #1186.

In openam-scripting, one such hook in GroovyValidatorTest was enough to make the scratch-class order above pass. Once the holder has been built, GuiceTestCase registers a fresh injector for every test method.

The limits that apply in openam-core-rest apply here too:

  • The hook covers the other classes only while surefire runs the module as one TestNG suite in one JVM, that is with the inherited forkCount=1 and reuseForks=true.
  • TestNG creates an instance of every test class before it runs any @BeforeSuite method. A constructor or initializer that reaches InjectorHolder still comes first.

Activity

  1. self-assigned this
    on Oct 20, 2026
  2. added 2 commits that reference this issue on Oct 20, 2026
  3. maximthomas commented on Oct 20, 2026

    @maximthomas
    ContributorAuthor

    RestRouterIT in openam-rest, raised in the #1188 review, is out of scope here. It installs an empty loader from a @BeforeMethod, but it needs none: the default loader builds the root injector on that module's test classpath. Measured on master 553b73f: a scratch class that touches InjectorHolder with no loader installed, run first, builds it, and RestRouterIT then passes 8 of 8. With its loader install deleted, RestRouterIT alone also passes 8 of 8. GuiceTestCase registers the test's own injector before each method and RestRouterIT reads only from that one, so class order cannot change its result.

  4. added
    testsTest suite: coverage, fixtures, or test infrastructure
    on Oct 20, 2026
  5. added a commit that references this issue on Oct 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugtestsTest suite: coverage, fixtures, or test infrastructure

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions