From 5f9ef67ad9dbe6c5006a738dc473132f3ca6dd12 Mon Sep 17 00:00:00 2001 From: maximthomas Date: Mon, 19 Oct 2026 11:12:04 +0300 Subject: [PATCH 1/4] Install the empty Guice module loader in openam-core-rest tests before the suite InjectorHolder builds its injector once per JVM, from the module loader in place at that moment. The modules on the openam-core-rest test classpath cannot be built (no NotificationBroker binding), so the first test that touches InjectorHolder with the default loader leaves the class unusable for the rest of the fork. SessionResourceV2Test.setUp constructs a real AMIdentity, whose constructor asks InjectorHolder for a RepoAuditorFactory and swallows the failure. IdentityResourceNotificationTest and SessionResourceTest installed an empty loader in @BeforeClass, which only helped when they ran before SessionResourceV2Test. Surefire runs the classes in file-system order, and on the ubuntu-26.04 runner image that order puts SessionResourceV2Test first: IdentityResourceNotificationTest.setupMocks fails with NoClassDefFoundError for InjectorHolder, and four more classes fail because its Realm mock was never torn down. Install the empty loader from @BeforeSuite(alwaysRun = true) in the three classes, so it is in place before the first test of the suite, whatever order the classes run in. --- .../IdentityResourceNotificationTest.java | 19 ++++++++++------ .../rest/session/SessionResourceTest.java | 11 ++++++---- .../rest/session/SessionResourceV2Test.java | 22 +++++++++++++++++++ 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java index c8b0db85ee..d43ea8c626 100644 --- a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java +++ b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java @@ -58,8 +58,8 @@ import org.forgerock.services.context.Context; import org.mockito.ArgumentCaptor; import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeSuite; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -113,15 +113,20 @@ public class IdentityResourceNotificationTest extends GuiceTestCase { * notification broker that is not there - so the first injector of this JVM has to be built from no modules at * all, and the bindings a test needs come from {@link #configure(Binder)}. * + * The loader is read once, while the first injector of the JVM is built, so it is installed before any test of + * the suite runs rather than before this class. Any earlier test that touches InjectorHolder with the default + * loader - {@code SessionResourceV2Test} constructs an {@code AMIdentity}, which asks for a + * {@code RepoAuditorFactory} and swallows the failure - leaves InjectorHolder unusable for the rest of the JVM, + * and a {@code @BeforeClass} here could not undo that. + * * The loader is not put back afterwards, and could not be: InjectorConfiguration exposes no way to read the * one in place, and the default implementation of it is not public either. It does not matter much, because - * the loader is read once, while the first injector of the JVM is built, and after this class has run that - * injector exists whatever the loader says. What a later test class in the same fork inherits is therefore an - * empty injector - which is what it would have got in this module anyway, since the real modules cannot be - * built here at all. A test that needs bindings has to bring them, the way this one does through - * {@link GuiceTestCase}, which is also what puts the injector back after every test method. + * once the first injector of the JVM exists the loader is never read again. What every test class in the same + * fork gets is therefore an empty injector - which is what it would have got in this module anyway, since the + * real modules cannot be built here at all. A test that needs bindings has to bring them, the way this one does + * through {@link GuiceTestCase}, which is also what puts the injector back after every test method. */ - @BeforeClass + @BeforeSuite(alwaysRun = true) public void setupGuiceModuleLoader() { InjectorConfiguration.setGuiceModuleLoader(new GuiceModuleLoader() { @Override diff --git a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java index 8a03d8c2dc..c5d0d8d051 100644 --- a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java +++ b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java @@ -88,8 +88,8 @@ import org.forgerock.util.promise.Promise; import org.mockito.ArgumentCaptor; import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeSuite; import org.testng.annotations.Test; public class SessionResourceTest { @@ -119,10 +119,13 @@ public class SessionResourceTest { * for a {@code RepoAuditorFactory}. If this class is the first in the fork to touch the injector holder, the holder builds * the injector from the modules of the running server, which cannot be built on this test classpath, and the holder * class then stays broken for every later test in the same JVM. Ask for an injector built from no modules instead, - * the way {@code IdentityResourceNotificationTest} does; the loader is only consulted while the first injector of the - * JVM is built, so this is a no-op when another class got there first. + * the way {@code IdentityResourceNotificationTest} does. + * + * The loader is only consulted while the first injector of the JVM is built, so it has to be in place before any + * test of the suite runs, not just before this class: a {@code @BeforeClass} comes too late whenever surefire happens + * to run {@code SessionResourceV2Test}, which constructs an {@code AMIdentity} too, ahead of this class. */ - @BeforeClass + @BeforeSuite(alwaysRun = true) public void setupGuiceModuleLoader() { InjectorConfiguration.setGuiceModuleLoader(new GuiceModuleLoader() { @Override diff --git a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceV2Test.java b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceV2Test.java index e9b3235f17..1b978097a1 100644 --- a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceV2Test.java +++ b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceV2Test.java @@ -31,10 +31,14 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import java.lang.annotation.Annotation; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Set; +import com.google.inject.Module; import com.iplanet.dpro.session.Session; import com.iplanet.dpro.session.SessionException; import com.iplanet.dpro.session.service.SessionService; @@ -44,6 +48,8 @@ import com.iplanet.sso.SSOTokenManager; import com.sun.identity.idm.AMIdentity; import com.sun.identity.idm.IdRepoException; +import org.forgerock.guice.core.GuiceModuleLoader; +import org.forgerock.guice.core.InjectorConfiguration; import org.forgerock.json.JsonPointer; import org.forgerock.json.resource.ActionRequest; import org.forgerock.json.resource.ActionResponse; @@ -77,6 +83,7 @@ import org.forgerock.util.query.QueryFilter; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeSuite; import org.testng.annotations.Test; public class SessionResourceV2Test { @@ -99,6 +106,21 @@ public class SessionResourceV2Test { private SessionResourceV2 sessionResource; + /** + * {@link #setUp()} constructs a real {@link AMIdentity}, which asks {@link org.forgerock.guice.core.InjectorHolder} + * for a {@code RepoAuditorFactory}. Have the injector built from no modules before any test of the suite runs, for + * the reason given on {@code SessionResourceTest#setupGuiceModuleLoader()}. + */ + @BeforeSuite(alwaysRun = true) + public void setupGuiceModuleLoader() { + InjectorConfiguration.setGuiceModuleLoader(new GuiceModuleLoader() { + @Override + public Set> getGuiceModules(Class moduleAnnotation) { + return Collections.emptySet(); + } + }); + } + @BeforeMethod public void setUp() throws Exception { From 5eb929e0e5a73cd4d8b8e6126124e2725047bdf6 Mon Sep 17 00:00:00 2001 From: maximthomas Date: Mon, 19 Oct 2026 14:29:11 +0300 Subject: [PATCH 2/4] Name any unhooked InjectorHolder user, not SessionResourceV2Test, as the reason for @BeforeSuite The javadocs of SessionResourceTest and IdentityResourceNotificationTest gave SessionResourceV2Test as the class that makes a @BeforeClass come too late. SessionResourceV2Test now installs the empty loader from its own @BeforeSuite hook, so that reason no longer holds. State the general one instead: any class that touches InjectorHolder without such a hook and runs first, with SessionResourceV2Test as the past example. --- .../openam/core/rest/IdentityResourceNotificationTest.java | 6 +++--- .../openam/core/rest/session/SessionResourceTest.java | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java index d43ea8c626..9153a9c875 100644 --- a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java +++ b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java @@ -115,9 +115,9 @@ public class IdentityResourceNotificationTest extends GuiceTestCase { * * The loader is read once, while the first injector of the JVM is built, so it is installed before any test of * the suite runs rather than before this class. Any earlier test that touches InjectorHolder with the default - * loader - {@code SessionResourceV2Test} constructs an {@code AMIdentity}, which asks for a - * {@code RepoAuditorFactory} and swallows the failure - leaves InjectorHolder unusable for the rest of the JVM, - * and a {@code @BeforeClass} here could not undo that. + * loader - as {@code SessionResourceV2Test} did before it got the same hook: it constructs an {@code AMIdentity}, + * which asks for a {@code RepoAuditorFactory} and swallows the failure - leaves InjectorHolder unusable for the + * rest of the JVM, and a {@code @BeforeClass} here could not undo that. * * The loader is not put back afterwards, and could not be: InjectorConfiguration exposes no way to read the * one in place, and the default implementation of it is not public either. It does not matter much, because diff --git a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java index c5d0d8d051..9f2730c513 100644 --- a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java +++ b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java @@ -122,8 +122,9 @@ public class SessionResourceTest { * the way {@code IdentityResourceNotificationTest} does. * * The loader is only consulted while the first injector of the JVM is built, so it has to be in place before any - * test of the suite runs, not just before this class: a {@code @BeforeClass} comes too late whenever surefire happens - * to run {@code SessionResourceV2Test}, which constructs an {@code AMIdentity} too, ahead of this class. + * test of the suite runs, not just before this class: a {@code @BeforeClass} comes too late whenever surefire runs, + * ahead of this class, any class that touches InjectorHolder without such a hook - as {@code SessionResourceV2Test}, + * which constructs an {@code AMIdentity} too, did before it got its own. */ @BeforeSuite(alwaysRun = true) public void setupGuiceModuleLoader() { From 0c41e0a916446c9c132f04146adee9db50d3dae2 Mon Sep 17 00:00:00 2001 From: maximthomas Date: Tue, 20 Oct 2026 14:11:05 +0300 Subject: [PATCH 3/4] Mock AMIdentity in the session resource tests instead of installing a loader SessionResourceTest and SessionResourceV2Test built a real AMIdentity only to return it from the stubbed SessionResourceUtil.getIdentity(), and the session code reads just getName() and getRealm() from it. The AMIdentity constructor asks InjectorHolder for a RepoAuditorFactory, which is why both classes had to install the empty module loader. Return a mock with those two getters stubbed instead, and drop both hooks: neither class touches InjectorHolder any more. IdentityResourceNotificationTest keeps its @BeforeSuite hook. Its javadoc now also says that TestNG creates an instance of every test class before it runs any @BeforeSuite method, so a constructor or initializer that reaches InjectorHolder still comes first, and that the hook covers the other classes only while the module runs as one TestNG suite in one JVM, as it does with the inherited forkCount=1 and reuseForks=true. --- .../IdentityResourceNotificationTest.java | 20 ++++++++--- .../rest/session/SessionResourceTest.java | 34 +++---------------- .../rest/session/SessionResourceV2Test.java | 29 +++------------- 3 files changed, 25 insertions(+), 58 deletions(-) diff --git a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java index 9153a9c875..dbe148c28c 100644 --- a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java +++ b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java @@ -115,16 +115,26 @@ public class IdentityResourceNotificationTest extends GuiceTestCase { * * The loader is read once, while the first injector of the JVM is built, so it is installed before any test of * the suite runs rather than before this class. Any earlier test that touches InjectorHolder with the default - * loader - as {@code SessionResourceV2Test} did before it got the same hook: it constructs an {@code AMIdentity}, - * which asks for a {@code RepoAuditorFactory} and swallows the failure - leaves InjectorHolder unusable for the - * rest of the JVM, and a {@code @BeforeClass} here could not undo that. + * loader - as the session resource tests did while they built a real {@code AMIdentity}, which asks for a + * {@code RepoAuditorFactory} and swallows the failure - leaves InjectorHolder unusable for the rest of the JVM, + * and a {@code @BeforeClass} here could not undo that. Even this hook does not always come first: TestNG creates + * an instance of every test class before it runs any {@code @BeforeSuite} method, so a constructor, field + * initializer or static initializer of a test class that reaches InjectorHolder still builds the injector from + * the default loader. A {@code mock(IdentityServicesImpl.class)} field is one such initializer, since the static + * fields of that class ask InjectorHolder for instances. * * The loader is not put back afterwards, and could not be: InjectorConfiguration exposes no way to read the * one in place, and the default implementation of it is not public either. It does not matter much, because - * once the first injector of the JVM exists the loader is never read again. What every test class in the same - * fork gets is therefore an empty injector - which is what it would have got in this module anyway, since the + * once the first injector of the JVM exists the loader is never read again. What every other test class of the + * suite gets is therefore an empty injector - which is what it would have got in this module anyway, since the * real modules cannot be built here at all. A test that needs bindings has to bring them, the way this one does * through {@link GuiceTestCase}, which is also what puts the injector back after every test method. + * + * The suite is the whole module only because the module inherits surefire's {@code forkCount=1} and + * {@code reuseForks=true}, which run all its test classes in one TestNG suite in one JVM. With + * {@code reuseForks=false} or a {@code forkCount} above 1 surefire runs each class in a suite of its own, and a + * class run alone - with {@code -Dtest} or from an IDE - runs without this hook. In those runs the hook guards + * this class at most, not the others. */ @BeforeSuite(alwaysRun = true) public void setupGuiceModuleLoader() { diff --git a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java index 9f2730c513..19c345bad7 100644 --- a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java +++ b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java @@ -32,7 +32,6 @@ import static org.mockito.Mockito.verify; import static org.testng.AssertJUnit.*; -import com.google.inject.Module; import com.iplanet.services.naming.WebtopNamingQuery; import com.iplanet.sso.SSOException; import com.iplanet.sso.SSOToken; @@ -42,7 +41,6 @@ import com.sun.identity.idm.AMIdentity; import com.sun.identity.idm.IdRepoException; import com.sun.identity.shared.debug.Debug; -import java.lang.annotation.Annotation; import java.security.Principal; import java.util.Arrays; import java.util.Collection; @@ -54,8 +52,6 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.assertj.core.api.Assertions; -import org.forgerock.guice.core.GuiceModuleLoader; -import org.forgerock.guice.core.InjectorConfiguration; import org.forgerock.http.session.Session; import org.forgerock.http.session.SessionContext; import org.forgerock.json.JsonValue; @@ -79,7 +75,6 @@ import org.forgerock.openam.rest.resource.SSOTokenContext; import org.forgerock.openam.session.SessionPropertyWhitelist; import org.forgerock.openam.test.apidescriptor.ApiAnnotationAssert; -import org.forgerock.opendj.ldap.DN; import org.forgerock.services.context.AttributesContext; import org.forgerock.services.context.ClientContext; import org.forgerock.services.context.Context; @@ -89,7 +84,6 @@ import org.mockito.ArgumentCaptor; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; -import org.testng.annotations.BeforeSuite; import org.testng.annotations.Test; public class SessionResourceTest { @@ -114,28 +108,6 @@ public class SessionResourceTest { - /** - * {@link #setUp()} constructs a real {@link AMIdentity}, whose constructor asks {@link org.forgerock.guice.core.InjectorHolder} - * for a {@code RepoAuditorFactory}. If this class is the first in the fork to touch the injector holder, the holder builds - * the injector from the modules of the running server, which cannot be built on this test classpath, and the holder - * class then stays broken for every later test in the same JVM. Ask for an injector built from no modules instead, - * the way {@code IdentityResourceNotificationTest} does. - * - * The loader is only consulted while the first injector of the JVM is built, so it has to be in place before any - * test of the suite runs, not just before this class: a {@code @BeforeClass} comes too late whenever surefire runs, - * ahead of this class, any class that touches InjectorHolder without such a hook - as {@code SessionResourceV2Test}, - * which constructs an {@code AMIdentity} too, did before it got its own. - */ - @BeforeSuite(alwaysRun = true) - public void setupGuiceModuleLoader() { - InjectorConfiguration.setGuiceModuleLoader(new GuiceModuleLoader() { - @Override - public Set> getGuiceModules(Class moduleAnnotation) { - return Collections.emptySet(); - } - }); - } - @BeforeMethod public void setUp() throws Exception { ssoTokenManager = mock(SSOTokenManager.class); @@ -153,7 +125,11 @@ public void setUp() throws Exception { realmContext = new RealmContext(mockContext, Realm.root()); - amIdentity = new AMIdentity(DN.valueOf("id=demo,dc=example,dc=com"), null); + // A mock, not a real AMIdentity: its constructor asks InjectorHolder for a RepoAuditorFactory, and on this + // classpath that leaves InjectorHolder unusable for every later test class in the JVM. + amIdentity = mock(AMIdentity.class); + given(amIdentity.getName()).willReturn("demo"); + given(amIdentity.getRealm()).willReturn("dc=example,dc=com"); configureWhitelist(); diff --git a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceV2Test.java b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceV2Test.java index 1b978097a1..cf7e5fecf6 100644 --- a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceV2Test.java +++ b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceV2Test.java @@ -31,14 +31,10 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; -import java.lang.annotation.Annotation; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.Set; -import com.google.inject.Module; import com.iplanet.dpro.session.Session; import com.iplanet.dpro.session.SessionException; import com.iplanet.dpro.session.service.SessionService; @@ -48,8 +44,6 @@ import com.iplanet.sso.SSOTokenManager; import com.sun.identity.idm.AMIdentity; import com.sun.identity.idm.IdRepoException; -import org.forgerock.guice.core.GuiceModuleLoader; -import org.forgerock.guice.core.InjectorConfiguration; import org.forgerock.json.JsonPointer; import org.forgerock.json.resource.ActionRequest; import org.forgerock.json.resource.ActionResponse; @@ -77,13 +71,11 @@ import org.forgerock.openam.session.SessionPropertyWhitelist; import org.forgerock.openam.test.apidescriptor.ApiAnnotationAssert; import org.forgerock.openam.utils.CrestQuery; -import org.forgerock.opendj.ldap.DN; import org.forgerock.services.context.Context; import org.forgerock.util.promise.Promise; import org.forgerock.util.query.QueryFilter; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; -import org.testng.annotations.BeforeSuite; import org.testng.annotations.Test; public class SessionResourceV2Test { @@ -106,21 +98,6 @@ public class SessionResourceV2Test { private SessionResourceV2 sessionResource; - /** - * {@link #setUp()} constructs a real {@link AMIdentity}, which asks {@link org.forgerock.guice.core.InjectorHolder} - * for a {@code RepoAuditorFactory}. Have the injector built from no modules before any test of the suite runs, for - * the reason given on {@code SessionResourceTest#setupGuiceModuleLoader()}. - */ - @BeforeSuite(alwaysRun = true) - public void setupGuiceModuleLoader() { - InjectorConfiguration.setGuiceModuleLoader(new GuiceModuleLoader() { - @Override - public Set> getGuiceModules(Class moduleAnnotation) { - return Collections.emptySet(); - } - }); - } - @BeforeMethod public void setUp() throws Exception { @@ -131,7 +108,11 @@ public void setUp() throws Exception { realmTestHelper = new RealmTestHelper(); realmTestHelper.setupRealmClass(); - amIdentity = new AMIdentity(DN.valueOf("id=demo,dc=example,dc=com"), null); + // A mock, not a real AMIdentity: its constructor asks InjectorHolder for a RepoAuditorFactory, and on this + // classpath that leaves InjectorHolder unusable for every later test class in the JVM. + amIdentity = mock(AMIdentity.class); + given(amIdentity.getName()).willReturn("demo"); + given(amIdentity.getRealm()).willReturn("dc=example,dc=com"); sessionService = mock(SessionService.class); partialSessionFactory = mock(PartialSessionFactory.class); From 31b6c8965fc83593adee9e324e917a8e81afacf7 Mon Sep 17 00:00:00 2001 From: maximthomas Date: Tue, 20 Oct 2026 15:56:11 +0300 Subject: [PATCH 4/4] State when a real AMIdentity leaves InjectorHolder unusable The setUp comments in SessionResourceTest and SessionResourceV2Test said the AMIdentity constructor leaves InjectorHolder unusable for every later test class. That happens only when it is the first call to reach the holder and no loader is installed yet. The IdentityResourceNotificationTest javadoc spoke of the static fields of IdentityServicesImpl. RESOURCE_MAPPING_HANDLER is the only one; idServicesErrorHandler is an instance field. --- .../openam/core/rest/IdentityResourceNotificationTest.java | 4 ++-- .../openam/core/rest/session/SessionResourceTest.java | 5 +++-- .../openam/core/rest/session/SessionResourceV2Test.java | 5 +++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java index dbe148c28c..445b26cb1e 100644 --- a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java +++ b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/IdentityResourceNotificationTest.java @@ -120,8 +120,8 @@ public class IdentityResourceNotificationTest extends GuiceTestCase { * and a {@code @BeforeClass} here could not undo that. Even this hook does not always come first: TestNG creates * an instance of every test class before it runs any {@code @BeforeSuite} method, so a constructor, field * initializer or static initializer of a test class that reaches InjectorHolder still builds the injector from - * the default loader. A {@code mock(IdentityServicesImpl.class)} field is one such initializer, since the static - * fields of that class ask InjectorHolder for instances. + * the default loader. A {@code mock(IdentityServicesImpl.class)} field is one such initializer, since a static + * field of that class asks InjectorHolder for an instance. * * The loader is not put back afterwards, and could not be: InjectorConfiguration exposes no way to read the * one in place, and the default implementation of it is not public either. It does not matter much, because diff --git a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java index 19c345bad7..825f78d05f 100644 --- a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java +++ b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceTest.java @@ -125,8 +125,9 @@ public void setUp() throws Exception { realmContext = new RealmContext(mockContext, Realm.root()); - // A mock, not a real AMIdentity: its constructor asks InjectorHolder for a RepoAuditorFactory, and on this - // classpath that leaves InjectorHolder unusable for every later test class in the JVM. + // A mock, not a real AMIdentity: its constructor asks InjectorHolder for a RepoAuditorFactory. If that is the + // first call to reach InjectorHolder in the JVM, before any loader is installed, it leaves InjectorHolder + // unusable on this classpath for every later test class. amIdentity = mock(AMIdentity.class); given(amIdentity.getName()).willReturn("demo"); given(amIdentity.getRealm()).willReturn("dc=example,dc=com"); diff --git a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceV2Test.java b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceV2Test.java index cf7e5fecf6..bcf17294b8 100644 --- a/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceV2Test.java +++ b/openam-core-rest/src/test/java/org/forgerock/openam/core/rest/session/SessionResourceV2Test.java @@ -108,8 +108,9 @@ public void setUp() throws Exception { realmTestHelper = new RealmTestHelper(); realmTestHelper.setupRealmClass(); - // A mock, not a real AMIdentity: its constructor asks InjectorHolder for a RepoAuditorFactory, and on this - // classpath that leaves InjectorHolder unusable for every later test class in the JVM. + // A mock, not a real AMIdentity: its constructor asks InjectorHolder for a RepoAuditorFactory. If that is the + // first call to reach InjectorHolder in the JVM, before any loader is installed, it leaves InjectorHolder + // unusable on this classpath for every later test class. amIdentity = mock(AMIdentity.class); given(amIdentity.getName()).willReturn("demo"); given(amIdentity.getRealm()).willReturn("dc=example,dc=com");