Skip to content

Commit ee1a9a0

Browse files
Fix JCasC startup crash caused by broken ManagementLink extensions (#2807)
1 parent 474a925 commit ee1a9a0

2 files changed

Lines changed: 83 additions & 4 deletions

File tree

plugin/src/main/java/io/jenkins/plugins/casc/RootElementConfigurator.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import io.jenkins.plugins.casc.impl.configurators.GlobalConfigurationCategoryConfigurator;
77
import java.util.ArrayList;
88
import java.util.List;
9+
import java.util.logging.Level;
10+
import java.util.logging.Logger;
911
import jenkins.model.GlobalConfigurationCategory;
1012
import jenkins.model.Jenkins;
1113

@@ -16,6 +18,8 @@
1618
*/
1719
public interface RootElementConfigurator<T> extends Configurator<T> {
1820

21+
Logger LOGGER = Logger.getLogger(RootElementConfigurator.class.getName());
22+
1923
static List<RootElementConfigurator> all() {
2024
final Jenkins jenkins = Jenkins.get();
2125
List<RootElementConfigurator> configurators =
@@ -26,10 +30,20 @@ static List<RootElementConfigurator> all() {
2630
}
2731

2832
for (ManagementLink link : ManagementLink.all()) {
29-
final String name = link.getUrlName();
30-
final Descriptor descriptor = Jenkins.get().getDescriptor(name);
31-
if (descriptor != null) {
32-
configurators.add(new DescriptorConfigurator(descriptor));
33+
try {
34+
final String name = link.getUrlName();
35+
if (name != null && !name.isEmpty()) {
36+
final Descriptor descriptor = Jenkins.get().getDescriptor(name);
37+
if (descriptor != null) {
38+
configurators.add(new DescriptorConfigurator(descriptor));
39+
}
40+
}
41+
} catch (Exception | LinkageError e) {
42+
LOGGER.log(
43+
Level.WARNING,
44+
"Failed to load configuration for ManagementLink: "
45+
+ link.getClass().getName() + ". Skipping.",
46+
e);
3347
}
3448
}
3549

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package io.jenkins.plugins.casc;
2+
3+
import static org.junit.Assert.assertFalse;
4+
import static org.junit.Assert.assertNotNull;
5+
6+
import hudson.model.ManagementLink;
7+
import java.util.List;
8+
import org.junit.Rule;
9+
import org.junit.Test;
10+
import org.jvnet.hudson.test.JenkinsRule;
11+
import org.jvnet.hudson.test.TestExtension;
12+
13+
public class RootElementConfiguratorTest {
14+
15+
@Rule
16+
public JenkinsRule j = new JenkinsRule();
17+
18+
@Test
19+
@SuppressWarnings("rawtypes")
20+
public void shouldSurviveBrokenManagementLink() {
21+
List<RootElementConfigurator> configurators = RootElementConfigurator.all();
22+
23+
assertNotNull("Configurators list should not be null", configurators);
24+
assertFalse("Should load at least some standard configurators", configurators.isEmpty());
25+
}
26+
27+
@TestExtension("shouldSurviveBrokenManagementLink")
28+
@SuppressWarnings("unused")
29+
public static class BrokenManagementLink extends ManagementLink {
30+
31+
@Override
32+
public String getIconFileName() {
33+
return null;
34+
}
35+
36+
@Override
37+
public String getDisplayName() {
38+
return "Broken Cluster Stats Link";
39+
}
40+
41+
@Override
42+
public String getUrlName() {
43+
throw new IllegalStateException("cannot call getRootUrlFromRequest from outside a request handling thread");
44+
}
45+
}
46+
47+
@TestExtension("shouldSurviveBrokenManagementLink")
48+
@SuppressWarnings("unused")
49+
public static class EmptyStringManagementLink extends ManagementLink {
50+
@Override
51+
public String getIconFileName() {
52+
return null;
53+
}
54+
55+
@Override
56+
public String getDisplayName() {
57+
return "Empty Link";
58+
}
59+
60+
@Override
61+
public String getUrlName() {
62+
return "";
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)