I have an issue with gradle and Jenkins, the CI server.
Running my buildscripts on my own machine works fine (windows), but running on Jenkins (linux) fails. The error is
Plugin with id ‘RemoteService’ not found.
The plugin in question is homemade, and lives in buildSrc. Looking at the log on the Jenkins machine does not bring revelations, at least not to me. It appears to identify and compile the plugin fine, but still it’s unable to locate it when it is applied?!
The plugin is called RemoteService.groovy. Here’s a debug dump from running a build on Jenkins:
https://docs.google.com/file/d/0BxgX3GzSY7VFZ1F5ak5TeVBVSDA/edit?usp=sharing
I have tried both with the installed gradle environment on Jenkins, and with the gradle wrapper. Same result. Both run gradle 1.4.
Could you please advice me what to do to make Jenkins locate the plugin?
Regards /Jesper Thuun-Petersen
Can you show the apply statement that throws the exception? Is ‘RemoteService’ really the ID of the plugin, rather than its class name?
the apply looks like this:
apply plugin: ‘RemoteService’
in the remoteservice.properties: implementation-class=RemoteService
Here’s the plugin code:
//import com.stibo.remoteserviceframework.server.impl.InterfaceGenerator
import java.util.logging.Logger
import org.gradle.api.Action
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.file.FileCollection
import org.gradle.api.logging.LogLevel
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.TaskAction
class RemoteService implements Plugin<Project> {
void apply(Project project) {
project.convention.plugins.remoteServiceConfiguration = new RemoteServiceConvention()
project.convention.getPlugin(JavaPluginConvention.class).sourceSets.all(
new Action<SourceSet>() {
public void execute(SourceSet sourceSet) {
final String taskName = sourceSet.getTaskName("generate", "RemoteService");
if (taskName.equals('generateRemoteService')) {
RemoteServiceTask remoteServiceTask = project.getTasks().add(taskName, RemoteServiceTask.class);
remoteServiceTask.description = String.format("Generates remote service interfaces %s.", sourceSet.name);
final String outputDirectoryName = "$project.buildDir/genclasses"
final File outputDirectory = new File(outputDirectoryName);
/*
remoteServiceTask.inputs.files project.sourceSets.main.java.srcDirs
remoteServiceTask.outputs.dir outputDirectory
*/
project.convention.plugins.remoteServiceConfiguration.destinationDir = outputDirectoryName
def classesTask = project.getTasks().getByName('classes')
classesTask.dependsOn(remoteServiceTask)
}
}
})
}
}
class RemoteServiceConvention {
def String sourcePackage
def String destinationPackage
def String destinationDir
def remoteService(Closure closure) {
closure.delegate = this
closure()
}
}
public class RemoteServiceTask extends DefaultTask {
private static final Logger LOGGER = Logger.getLogger("RemoteServiceTask");
@TaskAction
public void generate() {
def destinationDir = project.convention.plugins.remoteServiceConfiguration.destinationDir;
def sourcePackage = project.convention.plugins.remoteServiceConfiguration.sourcePackage;
def destinationPackage = project.convention.plugins.remoteServiceConfiguration.destinationPackage;
logging.level = LogLevel.DEBUG
println("Generating remote services to dir ${destinationDir}")
try {
ant.java(classname: 'com.stibo.remoteserviceframework.server.impl.InterfaceGenerator', fork: 'true', failOnError: 'true') {
arg(value: sourcePackage)
arg(value: destinationPackage)
arg(value: destinationDir)
sysproperty(key: "FRAMEWORK_DISABLE_AUTOINJECT", value: "true")
classpath {
pathelement(path: project.sourceSets.main.output.asPath)
pathelement(path: project.sourceSets.main.compileClasspath.asPath)
pathelement(location: "${project.mainProject}/remoteserviceframework/build/libs/remoteserviceframework-1.0-SNAPSHOT.jar")
}
}
} catch (Exception e) {
println "ERROR GENERATING INTERFACES: ${e.getMessage()}"
}
project.sourceSets.main.getOutput().dir(destinationDir);
}
}
A good first step is to try with the (fully qualified) class name instead. Something like ‘apply plugin: foo.bar.RemoteService’, or ‘apply plugin: RemoteService’ if it’s located in the default package.
Peter, thanks, that did work!
If I could just wrap my head around why I had it working on my own box but not on jenkins…
/J
Might be a case-(in)sensitive file system thing. If you use the same capitalization for the ‘apply’ statement and the filename of the properties file (which you always should), it will probably work on CI as well.