I'm a bit of a Grails newbie. I have an app which works fine in Eclipse but when I deploy in production falls over because of missing dependencies.
When I run the dependency report it shows all the dependencies are automatically present for 'build' but absent for 'runtime'.
What's the neatest way to migrate the dependencies from to runtime so (I hope) they get copied into my war file?
Also, I'm using the sanitizer plugin. This runs fine in development but has the dependencies missing from 'runtime' so falls over. If I manually add, for example, one of the dependencies into BuildConfig.groovy ("org.owasp.antisamy:antisamy:1.4.3") then grails falls over with this error:
loader constraint violation: loader (instance of ) previously initiated loading for a different type with name "org/xml/sax/SAXParseException"
I'm assuming that this is a classpath issue but I'm not sure why this only happens when I manually add the dependency - surely it's present all the time?
You're right, you have to add missing runtime dependencies to BuildConfig.groovy. The simplest thing would be to copy them from the plugin's BuildConfig.groovy to your app's one. You should also raise a JIRA for the respective grails plugin to get this fixed upstream.
Lots of jars out there in the Maven repositories have their dependencies not correctly defined in their pom file.
There is a way to fix that in BuildConfig.groovy, by switching off transitivity:
runtime('org.owasp.antisamy:antisamy:1.4.3') {
transitive = false
}
Instead of 'transitive=false' you might also experiment with excluding only specific dependencies using e.g.
excludes "xml-apis", "xerces"
inside the 'runtime' closure.
Related
Have a groovy controller leveraging Java SSH package (JSch) with NO ISSUES in IDE (jar was added to library, import works, all calls against class pass) however I get failure only on run-app:
unable to resolve class JSch # ... : JSch jsch = new JSch()
I use the same code in Java without any issues for an SFTP application and this won't even instantiate the initial object so less concerned about the rest of the code. I've tried mucking with dependency mgmt and refreshing with no success.
I guess the question at hand is why does any class fail to resolve only at run when there are no obvious issues with implementation?
Yeah... Grails doesn't give a damn about which jars you add with your IDE. Grails uses Maven to resolve dependencies.
Next steps
The first thing is to remove the JSch jar. Then, add the following Maven artifact to your project: com.jcraft:jsch:0.1.53
Of course, adjust the version number as needed. How this is added to Grails depends on the version of Grails you're using.
Grails 3
Add the following to the dependencies closure in build.gradle:
compile 'com.jcraft:jsch:0.1.53'
Grails 2.4
For Grails 2.4 (and maybe earlier versions, I simply don't know) add the following within the plugins closure in grails-app/config/BuildConfig.groovy
compile 'com.jcraft:jsch:0.1.53'
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.
I'm working with IntelliJ IDEA 10.0.1 and Grails 1.3.7. I have a mavenized Grails project which depends on many logging libraries.
Here's the problem:
I have to use JCL as logging framework, but grails per default is working with SLF4J and has some default dependencies like jcl-over-slf4j, which are inherited by every grails project. First of all I have excluded every jcl-over-slf4j transitive dependency in my project pom file and verified with mvn dependency:tree that my pom is clean of any SLF4J bridging libraries.
But nevertheless jcl-over-slf4j is still beeing downloaded to my local maven repo when I try to start my grails app. This leads obviously to a StackOverflowError at runtime, since both jcl-over-slf4j and slf4j-jcl are in the classpath.
So because of which declaration the jcl-over-slf4j dependency is still beeing downloaded?
Since my pom is clean the obvious conclusion would be that Grails itself depends on those libraries. As mentioned before Grails has some default dependencies, on which every Grails project depends.
I know that I can exclude inherited depencencies in the BuildConfig.groovy file and if I run grails dependency-report I can also see that these dependencies are not listed anymore.
grails.project.dependency.resolution = {
inherits("global") {
excludes "jcl-over-slf4j", "jul-to-slf4j", "slf4j-log4j12"
}
}
But even then the jcl-over-slf4j dependency is still beeing downloaded to my repo when I start my grails app! Am I missing something? Is there a different way to exclude inherited grails dependencies when you're using a mavenized grails project?
Any help would be appreciated
Thanks!
Slash
Ok I think I got the answer now..
The problem is that the defined maven-grails-plugin (which is mandatory when you use maven + grails) within my pom file depends on jcl-over-slf4j and therefore gets downloaded when I start my application through maven. With my current maven version (2.2.1) it's not possible to exclude a dependency from a plugin. There is also a jjira issue regarding this problem. Can not exclude a dependency from a plugin
As soon as I remove the maven-grails-plugin the dependency is not downloaded anymore, but as drawback I'm not able to start the application through maven anymore..
Lessons learned: Don't use Maven + Grails + JCL in conjunction.
Note that with mvn dependency:tree just project dependencies are listed, but plugin dependencies are NOT listed.
Hope this is of any help!
Regards Slash
Maybe I'm missing something about the way Gradle works. What I have here is a parent project, which only contains configuration, i.e. there won't be any artifact being built when building it, it merely manages and builds all its subprojects.
Now the subprojects share some dependency configuration, so I figured what I would do in the root project's build.gradle is:
subprojects {
dependencies {
compile fileTree(dir: 'lib', includes: ['*.jar'])
}
}
that, however, does not work, it fails with a rather obscure error message:
A problem occurred evaluating root
project 'qype-android' Cause: No
signature of method:
org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.compile()
is applicable for argument types:
(org.gradle.api.internal.file.DefaultConfigurableFileTree)
values: [file set 'lib'] Possible
solutions: module(java.lang.Object)
after some trial and error, I could "fix" this issue by applying the 'java' plugin to the parent project.
How come? I don't see anywhere from the Gradle docs that a fileTree dependency requires the Java plugin. Even so, why would I need it on the project that is injecting the configuration, as opposed to on the project that is being configured (note that the subprojects all apply the Java plugin themselves)?
Does this mean that if I have N different subprojects that are all of varying natures, and apply different plugins, that the parent projects must always apply the set of all plugins beings used somewhere to itself, too?
It is not the fileTree that requires 'java' plugin.
The error message is complaining about undefined compile dependency configuration. Java plugin defines this configuration for you, so that you can add dependencies (including your fileTree) to it.
I have installed spring-security-core in a grails project, but for some reason, IDEA didn't automatically pick up the jar files. I can deploy the app and run tests using the grails command line just fine... but IDEA still puts squiggly lines. Is there a way I can get IDEA to automatically pick up jars after I install plugins?
I'm not 100% what the real source of this problem is. To my knowledge, IntelliJ parses the BuildConfig.groovy inside plugins to configure dependencies. It seems, that it does not pickup the autogenerated dependencies.groovy. The packaged spring-security-core plugin just contains a dependencies.groovy and no BuildConfig.groovy.
I've added the following snippet to my app's BuildConfig.groovy
dependencies {
compile('org.springframework.security:org.springframework.security.core:3.0.2.RELEASE') {
excludes 'com.springsource.org.aopalliance',
'com.springsource.org.apache.commons.logging',
'org.springframework.beans',
'org.springframework.context',
'org.springframework.core'
}
compile('org.springframework.security:org.springframework.security.web:3.0.2.RELEASE') {
excludes 'com.springsource.javax.servlet',
'com.springsource.org.aopalliance',
'com.springsource.org.apache.commons.logging',
'org.springframework.aop',
'org.springframework.beans',
'org.springframework.context',
'org.springframework.core',
'org.springframework.web'
}
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
// runtime 'mysql:mysql-connector-java:5.1.5'
}
With this, IntelliJ "knows" about the Spring Security jars.
The problem in my case (9.0.2) was that the grailsPlugins did not have grails library on it's classpath. So the compile dependencies would not work, and your fix fabien is a bit to verbose :-)
IDEA normally has a great auto error fix (alt + enter) and it works in this case to. It will ask you to "Add grails user library to classpath". Works like a charm but should offcourse not be necessary
Open Project Structure Window
in Project Settings choose Modules
then choose the plugin module. It should be named "myproject-grailsPlugin"
then select the tab dependencies
Inside the dependent modules, select Grails User Library (if it does not exist, create it with Add -> Global Library)
EDIT this library and inside the Configure Module Library dialog, choose "Attach JAR directories"
Select the lib directory of the spring-security-code plugin. O windows it should be located ate : C:\Users\myuser.grails\1.3.1\projects\myproject\plugins\spring-security-core-0.3.1\lib
That's it !
why not just right click on your project root directory and click 'synchronize grails dependencies'...
It seems like intellij 9.0.3 does not correctly pick up dependencies from plugins when you change the plugin directory to something other other than default one in BuildConfig.groovy
grails.project.plugins.dir = "./plugins" //breaks plug-ins in intellij
Class not found errors started appearing after changing the plugin directory. I added the dependencies from the modules (namely spring-security-core and springcache) and now intellij adds the jar dependencies to 'Grails user library' and I can compile my app. Using the command line never had any issue.
Here's what I added to BuildConfig for springcache.
dependencies {
//for spring-security-core
// for springcache
compile("net.sf.ehcache:ehcache-web:2.0.0") {
excludes "ehcache-core" // ehcache-core is provided by Grails
}
}