I have a requirement that all the teams / developers in the organization should use same version of a module for example 1.2.15 version of log4j, 3.0.0.RELEASE version of org.springframework.core etc. So, I want developer to mention something like the following in their build file
I maintain another properties file that maps id to the corresponding group / name / version.
I will write a plugin that will read thirdPartyDependencies from build file and the properties file and would add the required dependencies programmatically.
I am not able to read the dependencies from the build file
I looked into DependencyHandler but did not get much clue.of adding the external dependency 3. How do I set transitive as false?
Have a look at the snippets in the comments of http://issues.gradle.org/browse/GRADLE-197 this should get you started on how to add dependencies by code (including transitive and exclude…).
If your plugin is in Groovy, you’d use exactly the same DSL.
So something like…
class ThirdPartyDependenciesExtension {
final Project project
def compile(Map dependency) {
add("compile", dependency)
}
def add(String scope, Map dependency) {
def id = dependency.id
def group = /* get group */
def version = /* get version */
project.dependencies {
delegate."$scope"("$id:$group:$version")
}
}
}
project.extensions.add("thirdPartyDependencies", new ThirdPartyDependenciesExtension(project: project))
That’s untested, but should get you started.
In general, it’s a good strategy to stick as close to the DSL layer as possible as it’s more understanable to regular Gradle users making it easier to maintain. It’s also less likely to change in future Gradle versions.
Thanks. I was using the 1.0-milestone-3. I have upgraded to 1.0-milestone-4. I have issue now.
I wrote custom plugin and placed that jar (pgplugin.jar) under D:\gradle-1.0-milestone-4\lib\plugins. It started throwing the following error -
Caused by: org.gradle.api.plugins.PluginInstantiationException: Could not find implementation class'null' for plugin 'pg' specified in jar:file:/D:/gradle-1.0-milestone-4/lib/plugins/pgplugin.jar!/META-INF/gradle-plugins/pg.properties.
at org.gradle.api.internal.plugins.DefaultPluginRegistry.getTypeForId(DefaultPluginRegistry.java:102)
at org.gradle.api.internal.plugins.DefaultPluginRegistry.getTypeForId(DefaultPluginRegistry.java:76)
at org.gradle.api.internal.plugins.DefaultProjectsPluginContainer.getTypeForId(DefaultProjectsPluginContainer.java:102)
at org.gradle.api.internal.plugins.DefaultProjectsPluginContainer.apply(DefaultProjectsPluginContainer.java:37)
at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.applyPlugin(DefaultObjectConfigurationAction.java:101)
at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.access$200(DefaultObjectConfigurationAction.java:32)
at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction$3.run(DefaultObjectConfigurationAction.java:72)
at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.execute(DefaultObjectConfigurationAction.java:114)
at org.gradle.api.internal.project.AbstractProject.apply(AbstractProject.java:845)
at org.gradle.api.Project$apply.call(Unknown Source)
at org.gradle.api.internal.project.ProjectScript.apply(ProjectScript.groovy:35)
at org.gradle.api.Script$apply.callCurrent(Unknown Source)
at build_7gslcdpg1pe0grk29isjrlf8sc.run(D:\B2D_PROJECTS-R36\commontech\pgutils\build.gradle:1)
at org.gradle.groovy.scripts.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:49)
... 26 more
Caused by: java.lang.ClassNotFoundException: com.pg.gradle.plugins.PGPlugin not found.
at org.gradle.util.MultiParentClassLoader.loadClass(MultiParentClassLoader.java:51)
at org.gradle.api.internal.plugins.DefaultPluginRegistry.getTypeForId(DefaultPluginRegistry.java:100)
... 39 more
The same plugin jar used to work under 1.0-milestone-3. Is there any change in classpath etc in milestone-4?
I see another file gradle-plugins-classpath.properties under your gradle-plugins-1.0-milestone-4.jar. Do I need to add similar file and what is the purpose of this?
If build script path can load custom plugin jar from $gradleHome/lib or $gradleHome/lib/plugins then the developer has to just give the following line -
apply plugin: 'pg'
I can put my custom jar under $gradleHome/lib or $gradleHome/lib/plugins and could create custom Gradle installer for my organization.
Is there any clean solution where each and every team / developer do not have to add that few lines of glue code for loading custom plugin in build scripts?
You don’t necessarily need to invent your own thirdPartyDependencies block for this. Your plugin can just provide a map of values which is used from the regular dependencies block as follows:
It’s good enough to set “project.libraries” for the root project; subprojects will see it automatically.
I like this solution because it’s simple and stays close to vanilla Gradle. On the other hand, a “thirdPartyDependencies” block gives you the power to implement a custom DSL.
To externalize the dependency information, you’d use standard programming techniques.
Adding any new third party dependency is bit difficult and error-prone as it has groovy / gradle code. I want to simplify and create a configuration file that holds third party dependencies and a plugin that reads configuration and creates project.libraries.
A plugin that read this configuration file and create project.libraries
class ThirdPartyLibraries implements Plugin<Project> {
public void apply(Project project) {
def config = new ConfigSlurper().parse(Tpd)
println config
project.libraries = [:]
config.flatten().each { key, value ->
project.libraries.put(key, value)
println "$key : $value"
}
}
}
I am getting the following error (below lines repeats several time) -
Caused by: java.lang.StackOverflowError
at org.gradle.util.FilteringClassLoader.allowed(FilteringClassLoader.java:142)
at org.gradle.util.FilteringClassLoader.loadClass(FilteringClassLoader.java:68)
at org.gradle.util.MultiParentClassLoader.loadClass(MultiParentClassLoader.java:46)
at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:112)
at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:61)
at org.gradle.api.internal.project.AbstractProject.dependencies(AbstractProject.java:880)
at org.gradle.api.Project$dependencies.call(Unknown Source)
at com.pg.gradle.plugins.ThirdPartyDependenciesExtension.compile(ThirdPartyDependenciesExtension.groovy:12)
at com.pg.gradle.plugins.ThirdPartyDependenciesExtension$_compile_closure1.doCall(ThirdPartyDependenciesExtension.groovy:13)
The stack trace indicates that ThirdPartyDependenciesExtension is used, so its seems you are somehow mixing both approaches. The way you add dependencies is unnecessarily complicated. “dependencies.create()” is just needed for advanced configuration. In the regular case you can do: