agent classloader

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 ?

5 comments
Comment actions Permalink

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
0
Comment actions Permalink

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.

0
Comment actions Permalink

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

0
Comment actions Permalink

Great, thanks.
Works like a charm now.

0
Comment actions Permalink

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?

0

Please sign in to leave a comment.