Skip to content

Commit 9d5ceac

Browse files
authored
Merge pull request #32994 from tjwatson/startPhaseCondition
Use a start phase condition to delay components according to current start-phase
2 parents f8638a0 + a53efd3 commit 9d5ceac

File tree

29 files changed

+872
-38
lines changed

29 files changed

+872
-38
lines changed

dev/com.ibm.ws.concurrent_fat_no_vt/publish/files/internalFeatures/virtualThreadDisabler-1.0.mf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ Subsystem-ManifestVersion: 1
22
IBM-ShortName: virtualThreadDisabler-1.0
33
Subsystem-SymbolicName: virtualThreadDisabler-1.0; visibility:=public
44
Subsystem-Version: 1.0.0
5-
Subsystem-Content: test.concurrent.no.vt.disabler; version="[1,1.1)"
5+
Subsystem-Content: test.concurrent.no.vt.disabler; version="[1,1.1)"; start-phase:=SERVICE_EARLY
66
Subsystem-Type: osgi.subsystem.feature
77
IBM-Feature-Version: 2

dev/com.ibm.ws.kernel.feature.core/src/com/ibm/ws/kernel/feature/internal/FeatureManager.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
*******************************************************************************/
1313
package com.ibm.ws.kernel.feature.internal;
1414

15+
import static com.ibm.wsspi.kernel.service.condition.StartPhaseCondition.StartPhase.ACTIVE;
16+
import static com.ibm.wsspi.kernel.service.condition.StartPhaseCondition.StartPhase.CONTAINER;
17+
import static com.ibm.wsspi.kernel.service.condition.StartPhaseCondition.StartPhase.PREPARE;
18+
import static com.ibm.wsspi.kernel.service.condition.StartPhaseCondition.StartPhase.SERVICE_EARLY;
19+
1520
import java.io.BufferedInputStream;
1621
import java.io.BufferedOutputStream;
1722
import java.io.DataInputStream;
@@ -761,8 +766,8 @@ protected void update(FeatureChange featureChange) throws IllegalStateException
761766
switch (featureChange.provisioningMode) {
762767
case INITIAL_PROVISIONING:
763768
// Get through kernel/core startup
764-
if (getStartLevel() < ProvisionerConstants.LEVEL_FEATURE_PREPARE) {
765-
BundleLifecycleStatus startStatus = setStartLevel(ProvisionerConstants.LEVEL_FEATURE_PREPARE);
769+
if (getStartLevel() < PREPARE.level()) {
770+
BundleLifecycleStatus startStatus = setStartLevel(PREPARE.level());
766771
checkBundleStatus(startStatus);
767772
}
768773
break;
@@ -832,7 +837,7 @@ protected void update(FeatureChange featureChange) throws IllegalStateException
832837
case INITIAL_PROVISIONING:
833838
// Increment the start level to ensure application bundles can start,
834839
// even if no features are loaded
835-
BundleLifecycleStatus startStatus = setStartLevel(ProvisionerConstants.LEVEL_ACTIVE);
840+
BundleLifecycleStatus startStatus = setStartLevel(ACTIVE.level());
836841
checkBundleStatus(startStatus); // FFDC, etc.
837842
checkServerReady();
838843

@@ -1638,8 +1643,8 @@ protected Result updateFeatures(WsLocationAdmin locService,
16381643
provisioner.installBundles(bundleContext,
16391644
bundleCache,
16401645
installStatus,
1641-
ProvisionerConstants.LEVEL_FEATURE_SERVICES - ProvisionerConstants.PHASE_INCREMENT,
1642-
ProvisionerConstants.LEVEL_FEATURE_CONTAINERS,
1646+
SERVICE_EARLY.level(),
1647+
CONTAINER.level(),
16431648
fwStartLevel.getInitialBundleStartLevel(),
16441649
locService);
16451650
// add all installed bundles to list of bundlesToStart.

dev/com.ibm.ws.kernel.feature.core/src/com/ibm/ws/kernel/feature/internal/ProvisionerConstants.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/*******************************************************************************
2-
* Copyright (c) 2009 IBM Corporation and others.
2+
* Copyright (c) 2009, 2025 IBM Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License 2.0
55
* which accompanies this distribution, and is available at
66
* http://www.eclipse.org/legal/epl-2.0/
7-
*
7+
*
88
* SPDX-License-Identifier: EPL-2.0
99
*
1010
* Contributors:
@@ -23,17 +23,6 @@ public interface ProvisionerConstants {
2323
/** Location of feature files */
2424
String LIB_FEATURE_PATH = "lib/features/";
2525

26-
/** Liberty Server start levels: 0 (stopped) has special meaning w/ OSGi */
27-
int LEVEL_FEATURE_PREPARE = 7,
28-
// The next 3 levels all support an early and late level. So changes to these numbers should
29-
// ensure there is at least 2 empty gaps between them.
30-
LEVEL_FEATURE_SERVICES = 9,
31-
LEVEL_FEATURE_CONTAINERS = 12,
32-
LEVEL_FEATURE_APPLICATION = 18,
33-
LEVEL_ACTIVE = 20;
34-
35-
int PHASE_INCREMENT = 1;
36-
3726
String PHASE_APPLICATION = "APPLICATION";
3827
String PHASE_APPLICATION_LATE = PHASE_APPLICATION + "_LATE";
3928
String PHASE_APPLICATION_EARLY = PHASE_APPLICATION + "_EARLY";

dev/com.ibm.ws.kernel.feature.core/src/com/ibm/ws/kernel/feature/internal/subsystem/FeatureResourceImpl.java

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
/*******************************************************************************
2-
* Copyright (c) 2011, 2023 IBM Corporation and others.
2+
* Copyright (c) 2011, 2025 IBM Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License 2.0
55
* which accompanies this distribution, and is available at
66
* http://www.eclipse.org/legal/epl-2.0/
7-
*
7+
*
88
* SPDX-License-Identifier: EPL-2.0
99
*
1010
* Contributors:
1111
* IBM Corporation - initial API and implementation
1212
*******************************************************************************/
1313
package com.ibm.ws.kernel.feature.internal.subsystem;
1414

15+
import static com.ibm.wsspi.kernel.service.condition.StartPhaseCondition.StartPhase.APPLICATION;
16+
import static com.ibm.wsspi.kernel.service.condition.StartPhaseCondition.StartPhase.APPLICATION_EARLY;
17+
import static com.ibm.wsspi.kernel.service.condition.StartPhaseCondition.StartPhase.APPLICATION_LATE;
18+
import static com.ibm.wsspi.kernel.service.condition.StartPhaseCondition.StartPhase.CONTAINER;
19+
import static com.ibm.wsspi.kernel.service.condition.StartPhaseCondition.StartPhase.CONTAINER_EARLY;
20+
import static com.ibm.wsspi.kernel.service.condition.StartPhaseCondition.StartPhase.CONTAINER_LATE;
21+
import static com.ibm.wsspi.kernel.service.condition.StartPhaseCondition.StartPhase.SERVICE;
22+
import static com.ibm.wsspi.kernel.service.condition.StartPhaseCondition.StartPhase.SERVICE_EARLY;
23+
import static com.ibm.wsspi.kernel.service.condition.StartPhaseCondition.StartPhase.SERVICE_LATE;
24+
1525
import java.util.ArrayList;
1626
import java.util.Collections;
1727
import java.util.HashMap;
@@ -22,7 +32,6 @@
2232
import java.util.concurrent.atomic.AtomicReference;
2333

2434
import org.osgi.framework.VersionRange;
25-
import org.osgi.framework.Version;
2635

2736
import com.ibm.websphere.ras.Tr;
2837
import com.ibm.websphere.ras.TraceComponent;
@@ -203,7 +212,7 @@ public int getStartLevel() {
203212
int result = _startLevel.get();
204213

205214
if (result == -1) {
206-
result = ProvisionerConstants.LEVEL_FEATURE_CONTAINERS;
215+
result = CONTAINER.level();
207216
// Directive names are in the attributes map, but end with a colon
208217
String phase = _rawAttributes.get("start-phase:");
209218

@@ -224,23 +233,23 @@ private int setStartLevel(String phase, int original) {
224233
}
225234

226235
if (ProvisionerConstants.PHASE_APPLICATION.equals(phase)) {
227-
return ProvisionerConstants.LEVEL_FEATURE_APPLICATION;
236+
return APPLICATION.level();
228237
} else if (ProvisionerConstants.PHASE_APPLICATION_LATE.equals(phase)) {
229-
return ProvisionerConstants.LEVEL_FEATURE_APPLICATION + ProvisionerConstants.PHASE_INCREMENT;
238+
return APPLICATION_LATE.level();
230239
} else if (ProvisionerConstants.PHASE_APPLICATION_EARLY.equals(phase)) {
231-
return ProvisionerConstants.LEVEL_FEATURE_APPLICATION - ProvisionerConstants.PHASE_INCREMENT;
240+
return APPLICATION_EARLY.level();
232241
} else if (ProvisionerConstants.PHASE_SERVICE.equals(phase)) {
233-
return ProvisionerConstants.LEVEL_FEATURE_SERVICES;
242+
return SERVICE.level();
234243
} else if (ProvisionerConstants.PHASE_SERVICE_LATE.equals(phase)) {
235-
return ProvisionerConstants.LEVEL_FEATURE_SERVICES + ProvisionerConstants.PHASE_INCREMENT;
244+
return SERVICE_LATE.level();
236245
} else if (ProvisionerConstants.PHASE_SERVICE_EARLY.equals(phase)) {
237-
return ProvisionerConstants.LEVEL_FEATURE_SERVICES - ProvisionerConstants.PHASE_INCREMENT;
246+
return SERVICE_EARLY.level();
238247
} else if (ProvisionerConstants.PHASE_CONTAINER.equals(phase)) {
239-
return ProvisionerConstants.LEVEL_FEATURE_CONTAINERS;
248+
return CONTAINER.level();
240249
} else if (ProvisionerConstants.PHASE_CONTAINER_LATE.equals(phase)) {
241-
return ProvisionerConstants.LEVEL_FEATURE_CONTAINERS + ProvisionerConstants.PHASE_INCREMENT;
250+
return CONTAINER_LATE.level();
242251
} else if (ProvisionerConstants.PHASE_CONTAINER_EARLY.equals(phase)) {
243-
return ProvisionerConstants.LEVEL_FEATURE_CONTAINERS - ProvisionerConstants.PHASE_INCREMENT;
252+
return CONTAINER_EARLY.level();
244253
} else {
245254
Tr.warning(tc, "INVALID_START_PHASE_WARNING", new Object[] { phase, this._symbolicName, this._featureName });
246255
return original;

dev/com.ibm.ws.kernel.feature_fat/.classpath

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<classpathentry kind="src" output="bin" path="fat/src"/>
1818
<classpathentry kind="src" path="test-bundles/test.feature.fix.manager/src"/>
1919
<classpathentry kind="src" path="test-bundles/test.active.condition/src"/>
20+
<classpathentry kind="src" path="test-bundles/test.startphase.condition/src"/>
2021
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
2122
<attributes>
2223
<attribute name="module" value="true"/>

dev/com.ibm.ws.kernel.feature_fat/bnd.bnd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ src: \
3232
test-bundles/test.override.requires.javax.swing.plaf/src, \
3333
test-bundles/test.feature.fragment.bundle/src, \
3434
test-bundles/test.feature.host.bundle/src, \
35-
test-bundles/test.active.condition/src
35+
test-bundles/test.active.condition/src, \
36+
test-bundles/test.startphase.condition/src
3637

3738
fat.project: true
3839

dev/com.ibm.ws.kernel.feature_fat/fat/src/com/ibm/ws/kernel/feature/fat/FATSuite.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2019, 2024 IBM Corporation and others.
2+
* Copyright (c) 2019, 2025 IBM Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License 2.0
55
* which accompanies this distribution, and is available at
@@ -43,7 +43,8 @@
4343
EECompatibilityTest.class,
4444
FeatureFragmentTest.class,
4545
FixManagerTest.class,
46-
ActiveConditionTest.class
46+
ActiveConditionTest.class,
47+
StartPhaseConditionTest.class
4748
})
4849
/**
4950
* Purpose: This suite collects and runs all known good test suites.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 IBM Corporation and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License 2.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* IBM Corporation - initial API and implementation
12+
*******************************************************************************/
13+
package com.ibm.ws.kernel.feature.fat;
14+
15+
import static org.junit.Assert.assertNotNull;
16+
import static org.junit.Assert.assertTrue;
17+
18+
import org.junit.After;
19+
import org.junit.AfterClass;
20+
import org.junit.BeforeClass;
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
24+
import componenttest.custom.junit.runner.FATRunner;
25+
import componenttest.topology.impl.LibertyServer;
26+
import componenttest.topology.impl.LibertyServerFactory;
27+
28+
@RunWith(FATRunner.class)
29+
public class StartPhaseConditionTest {
30+
private static LibertyServer server = LibertyServerFactory.getLibertyServer("com.ibm.ws.kernel.startphase.condition");
31+
32+
@Test
33+
public void testStartPhaseCondition() throws Exception {
34+
35+
server.startServer();
36+
server.stopServer(false);
37+
// The test has a different service component for each phase filter.
38+
// After starting and stopping the server we should see the following messages for PASSED
39+
String[] phases = { //
40+
"SERVICE_EARLY", //
41+
"SERVICE", //
42+
"SERVICE_LATE", //
43+
"CONTAINER_EARLY", //
44+
"CONTAINER", //
45+
"CONTAINER_LATE", //
46+
"APPLICATION_EARLY", //
47+
"APPLICATION", //
48+
"APPLICATION_LATE", //
49+
"ACTIVE" //
50+
};
51+
for (String phase : phases) {
52+
checkOnActivate(phase);
53+
}
54+
for (String phase : phases) {
55+
checkOnDeactivate(phase);
56+
}
57+
}
58+
59+
private void checkOnActivate(String phase) {
60+
String found = server.waitForStringInLog("ON_ACTIVATE TESTING StartPhaseCondition: " + phase + " - ");
61+
assertNotNull("No message found activate for phase: " + phase, found);
62+
assertTrue("Test failed: " + found, found.contains("PASSED"));
63+
}
64+
65+
private void checkOnDeactivate(String phase) {
66+
String found = server.waitForStringInLog("ON_DEACTIVATE TESTING StartPhaseCondition: " + phase + " - ");
67+
assertNotNull("No message found activate for phase: " + phase, found);
68+
assertTrue("Test failed: " + found, found.contains("PASSED"));
69+
}
70+
71+
@BeforeClass
72+
public static void installFeatures() throws Exception {
73+
server.installSystemFeature("test.startphase.condition-1.0");
74+
server.installSystemBundle("test.startphase.condition");
75+
}
76+
77+
@AfterClass
78+
public static void uninstallFeatures() throws Exception {
79+
server.uninstallSystemFeature("test.startphase.condition-1.0");
80+
server.uninstallSystemBundle("test.startphase.condition");
81+
}
82+
83+
@After
84+
public void tearDown() throws Exception {
85+
if (server != null && server.isStarted()) {
86+
server.stopServer();
87+
}
88+
server.postStopServerArchive();
89+
}
90+
91+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Subsystem-ManifestVersion: 1
2+
Subsystem-SymbolicName: test.startphase.condition-1.0; visibility:=public
3+
Subsystem-Version: 1.0.0
4+
Subsystem-Content: test.startphase.condition; start-phase:=SERVICE_EARLY
5+
Subsystem-Type: osgi.subsystem.feature
6+
IBM-Feature-Version: 2
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
com.ibm.ws.kernel.feature.enforce.public=true
2+
com.ibm.ws.logging.trace.specification=OSGi.Events=all
3+
bootstrap.include=../testports.properties

0 commit comments

Comments
 (0)