Skip to content

Conversation

@vwagh-dev
Copy link

@vwagh-dev vwagh-dev commented Mar 7, 2025

Issue:

Jenkins.getRootUrl() gets call very early in the Jenkins startup sequence causes CannotResolveClassException

com.thoughtworks.xstream.mapper.CannotResolveClassException: github-plugin-configuration
	at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:81)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:79)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:74)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:71)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at hudson.util.XStream2$CompatibilityMapper.realClass(XStream2.java:452)
	at hudson.util.xstream.MapperDelegate.realClass(MapperDelegate.java:46)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47)
	at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:135)
	at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
	at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1464)
	at hudson.util.XStream2.unmarshal(XStream2.java:230)
	at hudson.util.XStream2.unmarshal(XStream2.java:201)
	at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1441)
	at hudson.XmlFile.unmarshal(XmlFile.java:196)
Caused: java.io.IOException: Unable to read /tmp/joc-1-home/github-plugin-configuration.xml
	at hudson.XmlFile.unmarshal(XmlFile.java:199)
	at hudson.XmlFile.unmarshal(XmlFile.java:179)
	at hudson.model.Descriptor.load(Descriptor.java:933)
	at org.jenkinsci.plugins.github.config.GitHubPluginConfig.<init>(GitHubPluginConfig.java:86)
	at org.jenkinsci.plugins.github.config.GitHubPluginConfig$$FastClassByGuice$$1415135912.GUICE$TRAMPOLINE(<generated>)
	at org.jenkinsci.plugins.github.config.GitHubPluginConfig$$FastClassByGuice$$1415135912.apply(<generated>)
	at com.google.inject.internal.DefaultConstructionProxyFactory$FastClassProxy.newInstance(DefaultConstructionProxyFactory.java:82)
	at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:114)
	at com.google.inject.internal.ConstructorInjector.access$000(ConstructorInjector.java:33)
	at com.google.inject.internal.ConstructorInjector$1.call(ConstructorInjector.java:98)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:109)
	at hudson.ExtensionFinder$GuiceFinder$SezpozModule.onProvision(ExtensionFinder.java:607)
	at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:117)
	at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:93)
	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:300)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
	at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:169)
	at hudson.ExtensionFinder$GuiceFinder$FaultTolerantScope$1.get(ExtensionFinder.java:445)
	at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:45)
	at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1101)
	at hudson.ExtensionFinder$GuiceFinder._find(ExtensionFinder.java:403)
	at hudson.ExtensionFinder$GuiceFinder.find(ExtensionFinder.java:394)
	at hudson.ClassicPluginStrategy.findComponents(ClassicPluginStrategy.java:359)
	at hudson.ExtensionList.load(ExtensionList.java:384)
	at hudson.ExtensionList.ensureLoaded(ExtensionList.java:320)
	at hudson.ExtensionList.getComponents(ExtensionList.java:184)
	at hudson.DescriptorExtensionList.load(DescriptorExtensionList.java:213)
	at hudson.ExtensionList.ensureLoaded(ExtensionList.java:320)
	at hudson.ExtensionList.iterator(ExtensionList.java:172)
	at hudson.ExtensionList.getInstance(ExtensionList.java:162)
	at jenkins.model.JenkinsLocationConfiguration.get(JenkinsLocationConfiguration.java:65)
	at jenkins.model.Jenkins.getRootUrl(Jenkins.java:2461)

The error com.thoughtworks.xstream.mapper.CannotResolveClassException: github-plugin-configuration indicates that XStream is unable to resolve the class name github-plugin-configuration when trying to unmarshal the XML file

Fix:

Ensures that XStream can correctly map the github-plugin-configuration alias to the GitHubPluginConfig

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests - that demonstrates feature works or fixes the issue

Signed-off-by: Vishal Wagh <169045855+vwagh-dev@users.noreply.github.com>
@vwagh-dev vwagh-dev marked this pull request as ready for review March 9, 2025 11:17
@vwagh-dev vwagh-dev requested a review from a team as a code owner March 9, 2025 11:17
@vwagh-dev vwagh-dev marked this pull request as draft March 11, 2025 12:20
Comment on lines 87 to +88
getConfigFile().getXStream().alias("github-server-config", GitHubServerConfig.class);
getConfigFile().getXStream().alias(GITHUB_PLUGIN_CONFIGURATION_ID, GitHubPluginConfig.class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though the actual problem is that load() is called in the constructor it looks like a too involved fix to make that right. Instead all aliases already have a central point where they should be made.

Suggested change
getConfigFile().getXStream().alias("github-server-config", GitHubServerConfig.class);
getConfigFile().getXStream().alias(GITHUB_PLUGIN_CONFIGURATION_ID, GitHubPluginConfig.class);
GitHubPlugin.addXStreamAliases();

And add alias("github-server-config", GitHubServerConfig.class) to org.jenkinsci.plugins.github.migration.Migrator#enableAliases instead.

@rsandell
Copy link
Member

So the actual root cause of the problem we have seen internally is that there is a mechanism that calls Jenkins.getRootUrl() very early in the Jenkins startup sequence. Even before InitMilestone.SYSTEM_CONFIG_LOADED. And that is unraveling to load all extensions including GitHubPluginConfig for cing the configuration to be loaded too early. So org.jenkinsci.plugins.github.GitHubPlugin#addXStreamAliases won't have been called yet before the config is trying to be loaded.
But fixing that might have other consequences that we can't see now.

@vwagh-dev vwagh-dev marked this pull request as ready for review March 12, 2025 08:48
@vwagh-dev
Copy link
Author

Found the actual root cause & fixed it there only.

@vwagh-dev vwagh-dev closed this Mar 12, 2025
@azakharchenko-msol
Copy link

@vwagh-dev @rsandell Trying to fix the issue on jenkins server. Is there any suggested workaround to use?

@rsandell
Copy link
Member

Well in our case we made sure that the offender didn't call getRootUrl until after InitMileStone.SYSTEM_CONFIG_LOADED. For us it was doing it in Plugin.postInitialized , so we just changed that method to an @Initializer method instead.

@azakharchenko-msol
Copy link

Thank you, see the change f5f220f
It seems it does not always work as expected, because I still get an error like in PR title

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants