Repository: jenkinsci/prometheus-plugin (java)

Issue:
Prometheus Plugin Update prevents Jenkins from startup
### Jenkins and plugins versions report

Jenkins: 2.440.2
OS: Linux - 4.18.0-513.18.1.el8_9.x86_64
Java: 11.0.22 - Red Hat, Inc. (OpenJDK 64-Bit Server VM)
---
analysis-model-api:12.1.0
ansicolor:1.0.4
ant:497.v94e7d9fffa_b_9
antisamy-markup-formatter:162.v0e6ec0fcfcf6
apache-httpcomponents-client-4-api:4.5.14-208.v438351942757
asm-api:9.6-3.v2e1fa_b_338cd7
authentication-tokens:1.53.v1c90fd9191a_b_
badge:1.9.1
basic-branch-build-strategies:81.v05e333931c7d
bootstrap5-api:5.3.3-1
bouncycastle-api:2.30.1.77-225.v26ea_c9455fd9
branch-api:2.1152.v6f101e97dd77
build-timeout:1.32
build-user-vars-plugin:1.9
caffeine-api:3.1.8-133.v17b_1ff2e0599
checks-api:2.0.2
cloudbees-bitbucket-branch-source:880.vcf4056c5a_71f
cloudbees-folder:6.901.vb_4c7a_da_75da_3
cobertura:1.17
code-coverage-api:4.99.0
command-launcher:107.v773860566e2e
commons-lang3-api:3.13.0-62.v7d18e55f51e2
commons-text-api:1.11.0-95.v22a_d30ee5d36
conditional-buildstep:1.4.3
config-file-provider:968.ve1ca_eb_913f8c
content-replace:1.8.2
copyartifact:722.v0662a_9b_e22a_c
coverage:1.13.0
credentials:1337.v60b_d7b_c7b_c9f
credentials-binding:657.v2b_19db_7d6e6d
custom-tools-plugin:0.8
data-tables-api:2.0.2-1
dependency-track:4.3.1
display-url-api:2.200.vb_9327d658781
docker-commons:439.va_3cb_0a_6a_fb_29
docker-workflow:572.v950f58993843
durable-task:550.v0930093c4b_a_6
echarts-api:5.5.0-1
email-ext:2.105
exclusive-execution:0.8
extended-choice-parameter:381.v360a_25ea_017c
extended-read-permission:53.v6499940139e5
extra-tool-installers:139.v723fee51b_7f2
favorite:2.208.v91d65b_7792a_c
file-operations:214.v2e7dc7f25757
file-parameters:316.va_83a_1221db_a_7
font-awesome-api:6.5.1-3
forensics-api:2.4.0
generic-webhook-trigger:2.1.0
git:5.2.1
git-client:4.7.0
git-parameter:0.9.19
git-server:114.v068a_c7cc2574
gitlab-plugin:1.8.0
gradle:2.10
groovy:457.v99900cb_85593
groovy-postbuild:228.vcdb_cf7265066
gson-api:2.10.1-15.v0d99f670e0a_7
handy-uri-templates-2-api:2.1.8-30.v7e777411b_148
hidden-parameter:237.v4b_df26c7a_f0e
htmlpublisher:1.33
http_request:1.18
instance-identity:185.v303dc7c645f9
ionicons-api:56.v1b_1c8c49374e
jackson2-api:2.17.0-379.v02de8ec9f64c
jakarta-activation-api:2.1.3-1
jakarta-mail-api:2.1.3-1
javadoc:243.vb_b_503b_b_45537
javax-activation-api:1.2.0-6
javax-mail-api:1.6.2-9
jaxb:2.3.9-1
jdk-tool:73.vddf737284550
jersey2-api:2.42-147.va_28a_44603b_d5
jjwt-api:0.11.5-77.v646c772fddb_0
job-dsl:1.87
joda-time-api:2.12.7-29.v5a_b_e3a_82269a_
jquery:1.12.4-1
jquery3-api:3.7.1-2
jsch:0.2.16-86.v42e010d9484b_
json-api:20240303-41.v94e11e6de726
json-path-api:2.9.0-58.v62e3e85b_a_655
junit:1259.v65ffcef24a_88
ldap:719.vcb_d039b_77d0d
mailer:472.vf7c289a_4b_420
mapdb-api:1.0.9-28.vf251ce40855d
matrix-auth:3.2.2
matrix-project:822.824.v14451b_c0fd42
maven-plugin:3.23
metrics:4.2.21-449.v6960d7c54c69
mina-sshd-api-common:2.12.0-90.v9f7fb_9fa_3d3b_
mina-sshd-api-core:2.12.0-90.v9f7fb_9fa_3d3b_
msbuild:1.30
nodejs:1.6.1
okhttp-api:4.11.0-172.vda_da_1feeb_c6e
openshift-client:1.1.0.424.v829cb_ccf8798
pam-auth:1.10
pipeline-build-step:540.vb_e8849e1a_b_d8
pipeline-graph-analysis:216.vfd8b_ece330ca_
pipeline-groovy-lib:704.vc58b_8890a_384
pipeline-input-step:491.vb_07d21da_1a_fb_
pipeline-milestone-step:111.v449306f708b_7
pipeline-model-api:2.2184.v0b_358b_953e69
pipeline-model-definition:2.2184.v0b_358b_953e69
pipeline-model-extensions:2.2184.v0b_358b_953e69
pipeline-rest-api:2.34
pipeline-stage-step:305.ve96d0205c1c6
pipeline-stage-tags-metadata:2.2184.v0b_358b_953e69
pipeline-stage-view:2.34
pipeline-utility-steps:2.16.2
plain-credentials:179.vc5cb_98f6db_38
plugin-util-api:4.1.0
powershell:2.1
prism-api:1.29.0-13
prometheus:2.5.1 --> Upgrade to 2.5.2 not possible needed to rollback to backup
publish-over:0.22
publish-over-ssh:1.25
pubsub-light:1.18
purge-build-queue-plugin:88.v23b_97b_f2c7a_d
purge-job-history:1.6
rebuild:330.v645b_7df10e2a_
resource-disposer:0.23
role-strategy:713.vb_3837801b_8cc
run-condition:1.7
scm-api:689.v237b_6d3a_ef7f
script-security:1326.vdb_c154de8669
slave-setup:1.16
snakeyaml-api:2.2-111.vc6598e30cc65
sonar:2.17.2
sse-gateway:1.26
ssh-agent:346.vda_a_c4f2c8e50
ssh-credentials:326.v7fcb_a_ef6194b_
ssh-slaves:2.948.vb_8050d697fec
sshd:3.322.v159e91f6a_550
strict-crumb-issuer:2.1.1
structs:337.v1b_04ea_4df7c8
throttle-concurrents:2.14
timestamper:1.26
token-macro:400.v35420b_922dcb_
trilead-api:2.142.v748523a_76693
uno-choice:2.8.1
variant:60.v7290fc0eb_b_cd
warnings-ng:11.2.2
workflow-aggregator:596.v8c21c963d92d
workflow-api:1291.v51fd2a_625da_7
workflow-basic-steps:1049.v257a_e6b_30fb_d
workflow-cps:3889.v937e0b_3412d3
workflow-durable-task-step:1331.vc8c2fed35334
workflow-job:1400.v7fd111b_ec82f
workflow-multibranch:773.vc4fe1378f1d5
workflow-scm-step:427.v4ca_6512e7df1
workflow-step-api:657.v03b_e8115821b_
workflow-support:881.v7663695646cf
ws-cleanup:0.45


### What Operating System are you using (both controller, and any agents involved in the problem)?

Controller Node is Running RHEL 8

### Reproduction steps

Updating Prometheus Plugin to 2.5.2
Jenkins version is 2.440.2

### Expected Results

Jenkins should startup normally.

### Actual Results

Jenkins was stuck in startup process and throws errors in log.

### Anything else?

Log Messages attached:

`2024-03-26 14:08:26.920+0000 [id=43]	WARNING	o.j.p.prometheus.JobCollector#lambda$collect$0: Caught error when processing job [JOB] error: 
java.lang.IllegalStateException: Jenkins.instance is missing. Read the documentation of Jenkins.getInstanceOrNull to see what you are doing wrong.
	at jenkins.model.Jenkins.get(Jenkins.java:819)
	at org.jenkinsci.plugins.prometheus.config.PrometheusConfiguration.get(PrometheusConfiguration.java:79)
	at org.jenkinsci.plugins.prometheus.JobCollector.appendJobMetrics(JobCollector.java:215)
	at org.jenkinsci.plugins.prometheus.JobCollector.lambda$collect$0(JobCollector.java:162)
	at org.jenkinsci.plugins.prometheus.util.Jobs.forEachJob(Jobs.java:19)
	at org.jenkinsci.plugins.prometheus.JobCollector.collect(JobCollector.java:155)
	at io.prometheus.client.CollectorRegistry.collectorNames(CollectorRegistry.java:113)
	at io.prometheus.client.CollectorRegistry.register(CollectorRegistry.java:50)
	at org.jenkinsci.plugins.prometheus.service.DefaultPrometheusMetrics.registerCollectors(DefaultPrometheusMetrics.java:46)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at hudson.init.TaskMethodFinder.invoke(TaskMethodFinder.java:109)
	at hudson.init.TaskMethodFinder$TaskImpl.run(TaskMethodFinder.java:185)
	at org.jvnet.hudson.reactor.Reactor.runTask(Reactor.java:305)
	at jenkins.model.Jenkins$5.runTask(Jenkins.java:1170)
	at org.jvnet.hudson.reactor.Reactor$2.run(Reactor.java:221)
	at org.jvnet.hudson.reactor.Reactor$Node.run(Reactor.java:120)
	at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:68)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)
2024-03-26 14:08:26.910+0000 [id=23]	SEVERE	h.i.i.InstallUncaughtExceptionHandler$DefaultUncaughtExceptionHandler#uncaughtException: A thread (Jenkins initialization thread/23) died unexpectedly due to an uncaught exception. This may leave your server corrupted and usually indicates a software bug.
java.lang.ClassNotFoundException: hudson.util.HudsonFailedToLoad
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:476)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:594)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:527)
	at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:511)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:527)
Caused: java.lang.NoClassDefFoundError: hudson/util/HudsonFailedToLoad
	at hudson.WebAppMain$3.run(WebAppMain.java:276)`

### Are you interested in contributing a fix?

_No response_

Pull request:
Reverting commits which might cause startup issues on non docker instances
Fixes #647



Patch:
diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/context/Context.java b/src/main/java/org/jenkinsci/plugins/prometheus/context/Context.java
new file mode 100644
index 0000000..5d51634
--- /dev/null
+++ b/src/main/java/org/jenkinsci/plugins/prometheus/context/Context.java
@@ -0,0 +1,16 @@
+package org.jenkinsci.plugins.prometheus.context;
+
+import com.google.inject.AbstractModule;
+import hudson.Extension;
+import org.jenkinsci.plugins.prometheus.service.DefaultPrometheusMetrics;
+import org.jenkinsci.plugins.prometheus.service.PrometheusMetrics;
+
+@Extension
+public class Context extends AbstractModule {
+
+    @Override
+    public void configure() {
+        bind(PrometheusMetrics.class).to(DefaultPrometheusMetrics.class).in(com.google.inject.Singleton.class);
+    }
+
+}
diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/rest/PrometheusAction.java b/src/main/java/org/jenkinsci/plugins/prometheus/rest/PrometheusAction.java
index 35d1645..5e8f38d 100644
--- a/src/main/java/org/jenkinsci/plugins/prometheus/rest/PrometheusAction.java
+++ b/src/main/java/org/jenkinsci/plugins/prometheus/rest/PrometheusAction.java
@@ -1,7 +1,7 @@
 package org.jenkinsci.plugins.prometheus.rest;
 
+import com.google.inject.Inject;
 import hudson.Extension;
-import hudson.ExtensionList;
 import hudson.model.UnprotectedRootAction;
 import hudson.util.HttpResponses;
 import io.prometheus.client.exporter.common.TextFormat;
@@ -15,7 +15,14 @@ import org.kohsuke.stapler.StaplerResponse;
 
 @Extension
 public class PrometheusAction implements UnprotectedRootAction {
-    
+
+    private PrometheusMetrics prometheusMetrics;
+
+    @Inject
+    public void setPrometheusMetrics(PrometheusMetrics prometheusMetrics) {
+        this.prometheusMetrics = prometheusMetrics;
+    }
+
     @Override
     public String getIconFileName() {
         return null;
@@ -49,7 +56,6 @@ public class PrometheusAction implements UnprotectedRootAction {
     }
 
     private HttpResponse prometheusResponse() {
-        PrometheusMetrics prometheusMetrics = ExtensionList.lookupSingleton(PrometheusMetrics.class);
         return (request, response, node) -> {
             response.setStatus(StaplerResponse.SC_OK);
             response.setContentType(TextFormat.CONTENT_TYPE_004);
diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java b/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java
index e1f53fb..9024c9c 100644
--- a/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java
+++ b/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java
@@ -1,9 +1,6 @@
 package org.jenkinsci.plugins.prometheus.service;
 
-import hudson.Extension;
 import hudson.ExtensionList;
-import hudson.init.InitMilestone;
-import hudson.init.Initializer;
 import io.prometheus.client.Collector;
 import io.prometheus.client.CollectorRegistry;
 import io.prometheus.client.dropwizard.DropwizardExports;
@@ -13,8 +10,6 @@ import jenkins.metrics.api.Metrics;
 import org.jenkinsci.plugins.prometheus.*;
 import org.jenkinsci.plugins.prometheus.config.disabledmetrics.FilteredMetricEnumeration;
 import org.jenkinsci.plugins.prometheus.util.JenkinsNodeBuildsSampleBuilder;
-import org.kohsuke.accmod.Restricted;
-import org.kohsuke.accmod.restrictions.NoExternalUse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -22,40 +17,29 @@ import java.io.IOException;
 import java.io.StringWriter;
 import java.util.concurrent.atomic.AtomicReference;
 
-@Restricted(NoExternalUse.class)
-@Extension
 public class DefaultPrometheusMetrics implements PrometheusMetrics {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultPrometheusMetrics.class);
+    private static final Logger logger = LoggerFactory.getLogger(DefaultPrometheusMetrics.class);
 
-    private volatile boolean initialized = false;
-    private volatile boolean initializing = false;
     private final CollectorRegistry collectorRegistry;
     private final AtomicReference<String> cachedMetrics;
 
     public DefaultPrometheusMetrics() {
-        this.collectorRegistry = CollectorRegistry.defaultRegistry;
-        this.cachedMetrics = new AtomicReference<>("");
-    }
+        CollectorRegistry collectorRegistry = CollectorRegistry.defaultRegistry;
+        collectorRegistry.register(new JobCollector());
+        collectorRegistry.register(new JenkinsStatusCollector());
+        collectorRegistry.register(new DropwizardExports(Metrics.metricRegistry(), new JenkinsNodeBuildsSampleBuilder()));
+        collectorRegistry.register(new DiskUsageCollector());
+        collectorRegistry.register(new ExecutorCollector());
+        collectorRegistry.register(new CodeCoverageCollector());
 
-    @Initializer(after = InitMilestone.JOB_LOADED)
-    public void registerCollectors() {
-        if (!initialized && !initializing) {
-            initializing = true;
-            LOGGER.debug("Initializing...");
-            collectorRegistry.register(new JobCollector());
-            collectorRegistry.register(new JenkinsStatusCollector());
-            collectorRegistry.register(
-                    new DropwizardExports(Metrics.metricRegistry(), new JenkinsNodeBuildsSampleBuilder()));
-            collectorRegistry.register(new DiskUsageCollector());
-            collectorRegistry.register(new ExecutorCollector());
-            collectorRegistry.register(new CodeCoverageCollector());
-            // other collectors from other plugins
-            ExtensionList.lookup(Collector.class).forEach(collectorRegistry::register);
-            DefaultExports.initialize();
-            initialized = true;
-            initializing = false;
-        }
+        // other collectors from other plugins
+        ExtensionList.lookup(Collector.class).forEach(collectorRegistry::register);
+
+        DefaultExports.initialize();
+
+        this.collectorRegistry = collectorRegistry;
+        this.cachedMetrics = new AtomicReference<>("");
     }
 
     @Override
@@ -65,15 +49,11 @@ public class DefaultPrometheusMetrics implements PrometheusMetrics {
 
     @Override
     public void collectMetrics() {
-        if(!initialized) {
-            LOGGER.debug("Not initialized");
-            return;
-        }
         try (StringWriter buffer = new StringWriter()) {
             TextFormat.write004(buffer, new FilteredMetricEnumeration(collectorRegistry.metricFamilySamples().asIterator()));
             cachedMetrics.set(buffer.toString());
         } catch (IOException e) {
-            LOGGER.debug("Unable to collect metrics");
+            logger.debug("Unable to collect metrics");
         }
     }
 }
diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorker.java b/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorker.java
index b0aa93d..2955171 100644
--- a/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorker.java
+++ b/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorker.java
@@ -1,7 +1,7 @@
 package org.jenkinsci.plugins.prometheus.service;
 
+import com.google.inject.Inject;
 import hudson.Extension;
-import hudson.ExtensionList;
 import hudson.model.AsyncPeriodicWork;
 import hudson.model.TaskListener;
 import org.jenkinsci.plugins.prometheus.config.PrometheusConfiguration;
@@ -16,11 +16,16 @@ public class PrometheusAsyncWorker extends AsyncPeriodicWork {
 
     private static final Logger logger = LoggerFactory.getLogger(PrometheusAsyncWorker.class);
 
+    private PrometheusMetrics prometheusMetrics;
 
     public PrometheusAsyncWorker() {
         super("prometheus_async_worker");
     }
 
+    @Inject
+    public void setPrometheusMetrics(PrometheusMetrics prometheusMetrics) {
+        this.prometheusMetrics = prometheusMetrics;
+    }
 
     @Override
     public long getRecurrencePeriod() {
@@ -33,7 +38,6 @@ public class PrometheusAsyncWorker extends AsyncPeriodicWork {
     @Override
     public void execute(TaskListener taskListener) {
         logger.debug("Collecting prometheus metrics");
-        PrometheusMetrics prometheusMetrics = ExtensionList.lookupSingleton(PrometheusMetrics.class);
         prometheusMetrics.collectMetrics();
         logger.debug("Prometheus metrics collected successfully");
     }
diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusMetrics.java b/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusMetrics.java
index 9dadc68..fd5103e 100644
--- a/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusMetrics.java
+++ b/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusMetrics.java
@@ -1,8 +1,6 @@
 package org.jenkinsci.plugins.prometheus.service;
 
-import hudson.ExtensionPoint;
-
-public interface PrometheusMetrics extends ExtensionPoint {
+public interface PrometheusMetrics {
 
     String getMetrics();
 


Test patch:
diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/context/ContextTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/context/ContextTest.java
new file mode 100644
index 0000000..ea8d935
--- /dev/null
+++ b/src/test/java/org/jenkinsci/plugins/prometheus/context/ContextTest.java
@@ -0,0 +1,50 @@
+package org.jenkinsci.plugins.prometheus.context;
+
+import com.codahale.metrics.MetricRegistry;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import jenkins.metrics.api.Metrics;
+import jenkins.model.Jenkins;
+import org.jenkinsci.plugins.prometheus.config.PrometheusConfiguration;
+import org.jenkinsci.plugins.prometheus.service.DefaultPrometheusMetrics;
+import org.jenkinsci.plugins.prometheus.service.PrometheusMetrics;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import static org.mockito.Mockito.*;
+
+public class ContextTest {
+
+    @Test
+    public void testCanInjectContext() {
+        try (MockedStatic<Jenkins> jenkinsStatic = mockStatic(Jenkins.class);
+             MockedStatic<PrometheusConfiguration> prometheusConfigurationStatic = mockStatic(PrometheusConfiguration.class);
+             MockedStatic<Metrics> metricsStatic = mockStatic(Metrics.class)) {
+            Jenkins mockedJenkins = mock(Jenkins.class);
+            jenkinsStatic.when(Jenkins::get).thenReturn(mockedJenkins);
+
+            MetricRegistry mockedMetrics = mock(MetricRegistry.class);
+            metricsStatic.when(Metrics::metricRegistry).thenReturn(mockedMetrics);
+
+            PrometheusConfiguration mockedPrometheusConfiguration = mock(PrometheusConfiguration.class);
+            when(mockedPrometheusConfiguration.getLabeledBuildParameterNamesAsArray()).thenReturn(new String[]{});
+            when(mockedPrometheusConfiguration.getDefaultNamespace()).thenReturn("default");
+            prometheusConfigurationStatic.when(PrometheusConfiguration::get).thenReturn(mockedPrometheusConfiguration);
+
+            Injector injector = Guice.createInjector(new Context());
+            PrometheusMetrics prometheusMetrics = injector.getInstance(PrometheusMetrics.class);
+
+            Assertions.assertNotNull(prometheusMetrics);
+            Assertions.assertEquals(DefaultPrometheusMetrics.class, prometheusMetrics.getClass());
+
+            PrometheusMetrics prometheusMetrics2 = injector.getInstance(PrometheusMetrics.class);
+
+            Assertions.assertEquals(prometheusMetrics, prometheusMetrics2, "Should be the same as it's a singleton!");
+
+
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/rest/PrometheusActionTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/rest/PrometheusActionTest.java
index b750b67..58bc253 100644
--- a/src/test/java/org/jenkinsci/plugins/prometheus/rest/PrometheusActionTest.java
+++ b/src/test/java/org/jenkinsci/plugins/prometheus/rest/PrometheusActionTest.java
@@ -1,6 +1,5 @@
 package org.jenkinsci.plugins.prometheus.rest;
 
-import hudson.ExtensionList;
 import io.prometheus.client.exporter.common.TextFormat;
 import jenkins.metrics.api.Metrics;
 import jenkins.model.Jenkins;
@@ -92,24 +91,21 @@ public class PrometheusActionTest {
         PrometheusMetrics prometheusMetrics = mock(PrometheusMetrics.class);
         String responseBody = "testMetric";
         when(prometheusMetrics.getMetrics()).thenReturn(responseBody);
-        try (MockedStatic<ExtensionList> extensionListMockedStatic = mockStatic(ExtensionList.class)) {
-            extensionListMockedStatic.when(() -> ExtensionList.lookupSingleton(PrometheusMetrics.class)).thenReturn(prometheusMetrics);
-            StaplerRequest request = mock(StaplerRequest.class);
-            String url = "prometheus";
-            when(request.getRestOfPath()).thenReturn(url);
-
-            // when
-            HttpResponse actual = action.doDynamic(request);
-
-            // then
-            AssertStaplerResponse.from(actual)
-                    .call()
-                    .assertHttpStatus(HTTP_OK)
-                    .assertContentType(TextFormat.CONTENT_TYPE_004)
-                    .assertHttpHeader("Cache-Control", "must-revalidate,no-cache,no-store")
-                    .assertBody(responseBody);
-        }
+        action.setPrometheusMetrics(prometheusMetrics);
+        StaplerRequest request = mock(StaplerRequest.class);
+        String url = "prometheus";
+        when(request.getRestOfPath()).thenReturn(url);
+
+        // when
+        HttpResponse actual = action.doDynamic(request);
 
+        // then
+        AssertStaplerResponse.from(actual)
+            .call()
+            .assertHttpStatus(HTTP_OK)
+            .assertContentType(TextFormat.CONTENT_TYPE_004)
+            .assertHttpHeader("Cache-Control", "must-revalidate,no-cache,no-store")
+            .assertBody(responseBody);
     }
 
     private static class AssertStaplerResponse {
diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorkerTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorkerTest.java
index 2d6e911..8ba3677 100644
--- a/src/test/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorkerTest.java
+++ b/src/test/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorkerTest.java
@@ -1,6 +1,5 @@
 package org.jenkinsci.plugins.prometheus.service;
 
-import hudson.ExtensionList;
 import org.jenkinsci.plugins.prometheus.config.PrometheusConfiguration;
 import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.Issue;
@@ -21,15 +20,15 @@ public class PrometheusAsyncWorkerTest {
         // given
         PrometheusAsyncWorker asyncWorker = new PrometheusAsyncWorker();
         PrometheusMetrics metrics = new TestPrometheusMetrics();
-        try (MockedStatic<ExtensionList> extensionListMockedStatic = mockStatic(ExtensionList.class)) {
-            extensionListMockedStatic.when(() -> ExtensionList.lookupSingleton(PrometheusMetrics.class)).thenReturn(metrics);
-            // when
-            asyncWorker.execute(null);
+        asyncWorker.setPrometheusMetrics(metrics);
+
+        // when
+        asyncWorker.execute(null);
+
+        // then
+        String actual = metrics.getMetrics();
+        assertEquals("1", actual);
 
-            // then
-            String actual = metrics.getMetrics();
-            assertEquals("1", actual);
-        }
     }
     @Test
     public void testConvertSecondsToMillis() {