agent classloader Follow
We've just run into a problem with two different versions of jackson JSON mapping library.
- JFrog Artifactory plugin uses version 1.5.1
- Our plugin, White Source, (still under development) uses version 1.9.2
Both are transitive dependencies.
Other plugins may use various versions of other libraries as well.
Is it possible to have a separate classloader for agent side plugins?
Is there anything else we can do ?
Please sign in to leave a comment.
Hi Edo,
Try adding teamcity-plugin.xml in the root of the agent-side part with the content like:
<teamcity-agent-plugin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:shemas-jetbrains-com:teamcity-agent-plugin-v1-xml">
<plugin-deployment use-separate-classloader="true"/>
</teamcity-agent-plugin>
e.g see http://svn.jetbrains.org/teamcity/plugins/rake-runner/trunk/rake-runner-agent/teamcity-agent-plugin.xml
Honest thanks for the quick response. :)
Adding teamcity-plugin.xml caused my AgentLifeCycleListener not be initialized at all.
Happens when use-separate-classloader="false" as well.
I guess my spring context is not loaded this way.
We're currently developing for 6.5.x. Once done will start developing for 7.x.
Any other suggestions ?
Thanks again.
Hello,
TeamCity 6.5.x must support standalone classloading as Yegor suggested.
It looks like you packed your plugin in not correct way.
In case you put teamcity-plugin.xml file into the root of agent plugin .zip file,
you should not longer have a plugin-named folder in the root of artchive.
The plugin will be unpackged to the folder named same as .zip file (without extension).
So the layout of .zip file should be something like:
- teamcity-plugin.xml
- lib
- classes.jar
For more details, please take a look
http://blog.jonnyzzz.name/2011/09/how-to-pack-agent-plugin-for-teamcity.html
You may take NuGet plugin binarites as example of packing
http://teamcity.jetbrains.com/viewType.html?buildTypeId=bt375
Great, thanks.
Works like a charm now.
Hello,
I am having this same issue, except when I follow your solution I still end up getting the following stacktrace :
[2014-08-26 16:13:07,735] ERROR - gins.spring.SpringPluginLoader - Failed to initialize spring context for plugin myplugin
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from URL [jar:file:/TeamCity/buildAgent/lib/common-impl.jar!/META-INF/per-plugin-shared-spring.xml]; nested exception is org.springframework.beans.FatalBeanException: Class [org.springframework.context.config.ContextNamespaceHandler] for namespace [http://www.springframework.org/schema/context] does not implement the [org.springframework.beans.factory.xml.NamespaceHandler] interface
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:412)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:212)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:126)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:92)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:467)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:397)
at jetbrains.buildServer.plugins.spring.SpringPluginLoader$1.configsExtracted(SpringPluginLoader.java:65)
at jetbrains.buildServer.plugins.spring.SpringPluginConfigExtracter.start(SpringPluginConfigExtracter.java:42)
at jetbrains.buildServer.plugins.spring.SpringPluginLoader.pluginClassesLoaded(SpringPluginLoader.java:73)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at jetbrains.buildServer.util.EventDispatcher.dispatch(EventDispatcher.java:115)
at jetbrains.buildServer.util.EventDispatcher$2.invoke(EventDispatcher.java:67)
at com.sun.proxy.$Proxy6.pluginClassesLoaded(Unknown Source)
at jetbrains.buildServer.plugins.PluginManagerImpl$2.visitPlugin(PluginManagerImpl.java:122)
at jetbrains.buildServer.plugins.PluginsCollection.foreachLoadedPlugins(PluginsCollection.java:107)
at jetbrains.buildServer.plugins.PluginManagerImpl.firePluginClassesLoaded(PluginManagerImpl.java:120)
at jetbrains.buildServer.plugins.PluginManagerImpl.loadPlugins(PluginManagerImpl.java:80)
at jetbrains.buildServer.agent.plugins.AgentPluginsLoader.initializePlugins(AgentPluginsLoader.java:63)
at jetbrains.buildServer.agent.AgentMain2.loadPlugins(AgentMain2.java:129)
at jetbrains.buildServer.agent.AgentMain2.main(AgentMain2.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at jetbrains.buildServer.agent.AgentMain.main(AgentMain.java:41)
Caused by: org.springframework.beans.FatalBeanException: Class [org.springframework.context.config.ContextNamespaceHandler] for namespace [http://www.springframework.org/schema/context] does not implement the [org.springframework.beans.factory.xml.NamespaceHandler] interface
at org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve(DefaultNamespaceHandlerResolver.java:126)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1330)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1325)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:135)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:93)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390)
... 33 more
Any ideas?