Grails 2.2.X Plugin Development - Plugin Dependencies - grails

I'm totally confused how and where to specify my own plugin dependencies in Grails 2.2.X The documentation (Understanding Plugin Load Order) says that you can specify the dependencies in plugin descriptor class MyGrailsPlugin.groovy. Whereas, the "Upgrading from" chapter says that only pom dependencies will be taken into account. As I understand this unclear statement, only if I would specify the dependency in BuildConfig as a compile dependency that it would be used.
Using dependsOn brought me some problems in my main application (could not resolve a dependency in plugin even if it exists - I think some wild card problem "def dependsOn =['jquery-ui': "* > 1.8.24"]").
The only way how the plugin dependency works for me is specifying it in BuildConfig (MyPlugin):
grails.project.work.dir = 'target'
grails.project.dependency.resolution = {
inherits 'global'
log 'warn'
repositories {
grailsCentral()
mavenLocal()
mavenCentral()
}
plugins {
build(':release:2.2.1', ':rest-client-builder:1.0.3') {
export = false
}
compile ":resources:1.1.6"
compile ":jquery:1.8.3"
compile ":jquery-ui:1.8.24"
}
}
But my application uses resources plugin of version 1.2. When I run the app it always asks me if I'd like to upgrade to 1.1.6.
So the question is, how and where should I specify my dependencies.
Thanks,
Mateo

Actually, I am using grails 2.1.0. In that i replace resource with 1.2( runtime ":resources:1.2") in BuildConfig.groovy.
And then refresh dependencies. It is worked fine.

After reading more about Grails plug-in I realized that this behavior makes sense. If the plugin specify certain version of its dependency and your project specifies a different one, you're in conflict. You need to use following in order to exclude dependecy from the plugin and use yours:
runtime ":resources:1.2"
compile ':my-plugin:2.0.8', {
exclude 'resources'
}
In this case the plugin creator cannot assure that his plugin will run properly with newer version of dependency.
Regarding the resources plugin dependency. In my opinion it is better to use following
compile ":resources:1.1.6" {
export = false
}
which won't include the dependency for your plugin. This should be used just when you defines some ApplicationResources.groovy. If you use something from this plugin in your plugin you should not exclude resource plugin...
In my opinion you should specify your plugin dependencies in BuildConfig.groovy
Hope these things will be improved in further Grails versions.
Further reading from Burt:
http://www.slideshare.net/burtbeckwith/plugins-21828912

Related

How to install plugins in grails-3.2.0 which i have used in grails-2.4.4 while upgrading application

I am trying to upgrade my application from Grails 2.4.4 to Grails 3.2.0. I am having problems installing plugins used in previous version. Following Questions did gave me some clarification :
1) First one
2) Second one
Now I have few plugins like tomcat, jquery,etc which are not available at https://bintray.com/grails/plugins as described in First one question.
So can you tell me how do I add plugins which are not in this directory on plugins at bintray.
There is some problem as well I am using database-migration plugin. There is listing available at bintray and says to use it as
compile 'org.grails.plugins:database-migration:3.0.0'
as I added same in build.gradle file in my project under dependencies section. Project gets compiled successfully but does not run. Shows long exception but starting is as follows :
org.gradle.api.tasks.TaskExecutionException: Execution failed for task
':bootRun'.
Please help to resolve this errors while installing plugin in Grails 3.2.0
You need an extra configuration for that plugin as its doc says.
Add in build.gradle
buildscript {
dependencies {
...
classpath 'org.grails.plugins:database-migration:3.0.0'
}
}
dependencies {
...
compile 'org.grails.plugins:database-migration:3.0.0'
}
It is also recommended to add a direct dependency to liquibase because Spring Boot overrides the one provided by this plugin
dependencies {
...
compile 'org.liquibase:liquibase-core:3.5.3'
}
You should also tell Gradle about the migrations folder
sourceSets {
main {
resources {
srcDir 'grails-app/migrations'
}
}
}
Maybe plugins are no longer necessary and don't have direct replacements. The tomcat plugin is not needed because Grails 3 is built on Spring Boot and the dependency:
compile "org.springframework.boot:spring-boot-starter-tomcat"
Provides tomcat already. The jQuery plugin is not needed either because you can simply declare a dependency on the jquery.js file directly using asset pipeline which is just as simple. See How to Use jQuery in Grails 3.0

Why are there two ways to configure plugins for grails?

A grails application I work with has two ways to include plugins:
first in the application.properties file:
plugins.cache-headers=1.0.4
plugins.cached-resources=1.1
plugins.database-migration=1.1
plugins.export=1.5
plugins.font-awesome-resources=3.2.1.2
and in the BuildConfig.groovy file:
runtime ":resources:1.1.6"
compile ":database-migration:1.3.6"
compile ":quartz:0.4.2"
compile ":export:1.5"
compile ":font-awesome-resources:3.2.1.2"
It seems confusing that the database migration plugin is version 1.1 in application resources and 1.3.6 in BuildConfig.
Why are there two ways to configure plugins for grails?
Yes there are two ways of installing plugins.
The old way of declaring dependencies, using the command install-plugin. This will work with application.properties.
In Grails 2.x the preferred way is to use BuildConfig.groovy since this is more flexible, you can exclude jars/dependencies, define the scope and config the dependency to not be exported.
plugins {
test() //test scoped plugin
compile("group:name:version") {
excludes "some-dependency" //install the plugin, but not his dependency
}
compile("...") {
export = false //use this dependency, but not export.
}
}
With install-plugin, all your dependencies will be compile scoped.
More about in this discussion.

Adding Spring Security dependency to Grails plugin

I am developing a Grails 2.2.3 plugin for internal use, and in the plugin I would like to have the configured security settings that I use in every app. Spring Security config, Spring Security LDAP config, and custom UserDetails class and UserDetailsContextMapper class.
I have all of that taken care of, but the issue I'm having is that I cannot get the dependencies to work correctly in the plugin. It works fine if the app using the plugin into declares spring-security-core and spring-security-ldap in its plugin dependencies, but apps shouldn't have to declare this dependency - the plugin should take care of it.
So how do I get this plugin to install and use the spring-security-core and spring-security-ldap plugins correctly? Here is my BuildConfig.groovy file in the plugin:
plugins {
compile ":spring-security-core:1.2.7.3"
compile ":spring-security-ldap:1.0.6"
//Putting this in the app USING the plugin makes it work fine.
}
The plugins block is correct. If it's not working after installing from a zip, you might have some cruft left over from before.
To keep things in one place, I like to remove
grails.project.class.dir = "target/classes"
grails.project.test.class.dir = "target/test-classes"
grails.project.test.reports.dir = "target/test-reports"
and replace them with
grails.project.work.dir = 'target'
so everything is under the target folder. When things get weird, run rm -rf target to force a full re-resolve and rebuild.
Then, rather than using inline plugins (which aren't great about transitive deps because we read that info from POM files now and that's not available unless you package the plugin properly) or zips, use the release plugin's maven-install script.
Add this to the plugins section (removing any older version you might have):
build ':release:2.2.1', ':rest-client-builder:1.0.3', {
export = false
}
and after running grails compile to get it resolved, the maven-install script will be available. This packages your plugin and copies it to the right place in your $HOME/.m2/repository folder. Then if you add or uncomment mavenLocal() in the repositories block in your application's BuildConfig.groovy, you can just add a dependency for your plugin in your application as if it were released in the main repo, e.g.
plugins {
compile ':my-cool-security-plugin:0.1'
}
Re-run grails maven-install periodically when you make changes to the plugin, and delete the target directory to force a reinstall in the app.

Grails BuildConfig.groovy, difference between build, compile, and runtime?

What's the difference between build, runtime, and compile, in BuildConfig.groovy (1.3.7)
grails.project.dependency.resolution = {
plugins {
build "acme:acme-cache:latest.integration"
}
dependencies {
build "com.foo.bar:foobar:1.0.5"
runtime "org.apache.httpcomponents:httpclient:4.0.3"
compile("com.thoughtworks.xstream:xstream:1.3.1")
}
}
build - dependency that is only needed by the build process
runtime - dependency that is needed to run the application, but not compile it e.g. JDBC implementation for specific database vendor. This would not typically be needed at compile-time because code depends only the JDBC API, rather than a specific implementation thereof
compile - dependency that is needed at both compile-time and runtime. This is the most common case
There are a couple of other dependency scopes:
test - dependency that is only needed by the tests, e.g. a mocking/testing library
provided - dependency that is needed at compile-time but should not be packaged with the app (usually because it is provided by the container). An example is the Servlet API
It seems the 2 previous answers conflict on the distinction between compile and build. I believe that build is the scope that includes grails compile and grails run-app, while compile is just the former.
Starting from Grails 3, dependencies are managed by Gradle. The grails-app/conf/BuildConfig.groovy file has been replaced by the build.gradle file in the project's root.
The Grails user guide explain how to set grails depencies with gradle. See also the related Gradle documentation for further details on managing dependencies using it.
A couple grails commands help illustrate the difference. Consider grails run-app and grails compile. grails compile is the compile step and will include compile-time dependencies. grails run-app is the run step and will include runtime dependencies. Build dependencies are anything that you might need to run any of these commands, for example, a custom script that hooks into some build events.
So you would pick the one that best fits when you need to be certain the dependency is included.

Grails Plugin Maven Integration

I'm trying to create Mavenized Grails application. Everything works fine but as I understood all the dependencies (all .jars like mysql-connector and also all grails (public) plugins like spring-security-core plugin) should be listed in pom.xml.
The thing is that I don't know how to include public grails plugins (is there any Maven repository for that, or should I include used plugins into my local repo?). Or is the proper way how to handle grails plugin to list them in "application.properties" and let the grails to manage these plugins?
Thank you for any comment.:-)
Mateo
You can specify your plugin dependencies in grails-app/conf/BuildConfig.groovy, for example:
grails.project.dependency.resolution = {
plugins {
runtime ':hibernate:1.2.1'
}
}
Update
In response to your comments below, a plugin dependency specified in BuildConfig.groovy (or application.properties) will still be resolved by Grails rather than Maven. I don't think there's any way that you can get Maven to resolve a Grails plugin dependency, because Maven can only work with JAR dependencies in Maven repositories. Remember, Grails plugins are not (typically) available from Maven repositories.
If you want to hand as much control as possible over to Maven, you can try excluding the JARs from your plugin dependencies, e.g.
plugins {
runtime( "org.grails.plugins:hibernate:1.2.1" ) {
excludes "javassist"
}
}
and add them to your pom.xml instead. Here be dragons (see below).
Editorializing
FWIW, unless you really have to build your Grails project with Maven (e.g. because another Maven project depends on it), my advice would be don't. I say this because Maven is very much a second-class citizen in the world of Grails build tools. The usual way to build a Grails app is using the built-in GAnt commands. Future versions of Grails will move towards Gradle as the default build tool, so it seems that Maven will be an afterthought for the forseeable future
By default, Grails plugins are included at the source level. A plugin zip is expanded, and the plugin source is compiled as part of the grails build process.
Since 2.0, grails can use binary plugins. You can depend on plain old JARS if those jars represent binary grails plugins.
Binary grails plugins can be referenced by normal maven coordinates.
Your project's BuildConfig.groovy is where you specify maven repositories and binary plugins.

Resources