Should dependencies in the buildscript section be added to the current context classloader?


(gradle) #1

Hi all

I’m trying to hack the gradle cargo plugin (https://github.com/bmuschko/gradle-cargo-plugin) to support the cargo custom configuration mechanism (http://cargo.codehaus.org/Custom+Configuration). This requires passing a class name through to the cargo ant task that the cargo plugin delegates to.

The underlying ant task throws a ClassNotFoundException when trying to load the class, though. It looks like it’s calling Class.forName(), and seemingly the one classloader that doesn’t have my dependency in it is the current thread classloader, which is what Class.forName will search.

Caused by: : java.lang.ClassNotFoundException: my.custom.CargoConfigClass

at org.apache.tools.ant.IntrospectionHelper$6.set(IntrospectionHelper.java:1097)

at org.apache.tools.ant.IntrospectionHelper$AttributeSetter.setObject(IntrospectionHelper.java:1493)

at org.apache.tools.ant.IntrospectionHelper.setAttribute(IntrospectionHelper.java:411)

at org.apache.tools.ant.RuntimeConfigurable.maybeConfigure(RuntimeConfigurable.java:489)

at org.apache.tools.ant.RuntimeConfigurable.maybeConfigure(RuntimeConfigurable.java:429)

at org.apache.tools.ant.UnknownElement.handleChild(UnknownElement.java:592)

at org.apache.tools.ant.UnknownElement.handleChildren(UnknownElement.java:358)

at org.apache.tools.ant.UnknownElement.configure(UnknownElement.java:204)

at org.apache.tools.ant.UnknownElement.maybeConfigure(UnknownElement.java:163)

at org.gradle.api.internal.project.ant.BasicAntBuilder.nodeCompleted(BasicAntBuilder.java:71)

at org.gradle.api.internal.project.ant.BasicAntBuilder.doInvokeMethod(BasicAntBuilder.java:86)

at org.gradle.api.internal.project.DefaultAntBuilder.super$3$invokeMethod(DefaultAntBuilder.groovy)

at org.gradle.api.internal.project.DefaultAntBuilder.invokeMethod(DefaultAntBuilder.groovy:37)

at org.gradle.api.plugins.cargo.tasks.local.LocalCargoContainerTask.runAction(LocalCargoContainerTask.groovy:183)

at org.gradle.api.plugins.cargo.tasks.AbstractCargoContainerTask$_start_closure1.doCall(AbstractCargoContainerTask.groovy:92)

at org.gradle.api.plugins.cargo.tasks.AbstractCargoContainerTask$_start_closure1.doCall(AbstractCargoContainerTask.groovy)

at org.gradle.api.plugins.cargo.util.LoggingHandler.withAntLoggingListener(LoggingHandler.groovy:38)

at org.gradle.api.plugins.cargo.util.LoggingHandler$withAntLoggingListener.call(Unknown Source)

at org.gradle.api.plugins.cargo.tasks.AbstractCargoContainerTask.start(AbstractCargoContainerTask.groovy:91)

at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)

at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:219)

at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:212)

at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:201)

at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:533)

at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:516)

at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)

at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)

… 43 more

Caused by: java.lang.ClassNotFoundException: my.custom.CargoConfigClass

at org.apache.tools.ant.IntrospectionHelper$6.set(IntrospectionHelper.java:1095)

… 69 more

I suppose that the cargo plugin could be made to set and reset the context classloader around execution of its tasks, but given that I’d chucked the dependency that contains the class into the buildscript classpath, I would have expected it to already be there.

So the question is: Should dependencies in the buildscript section be added to the current context classloader? If not, why not? And is there any other solution available to me than hacking the context classloader?

Thanks

Tom


(gradle) #2

OK, so I had a mistake in my debug code - the class IS available on the current thread’s context classloader. It’s NOT available on the classloader associated with the gradle task’s class, which is what Class.forName seems to be using.

Unsure what to do now - setting the thread context classloader is useless, since it’s not being used by the Ant IntrospectionHelper.

Suggestions?