In Grails, how do I specify jars needed by an ivy resolver?

笑着哭i 提交于 2019-12-02 09:39:43

问题


In a grails project I have added a custom ivy resolver per the reference docs, http://www.grails.org/doc/latest/guide/single.html#12.2%20Plugin%20Repositories .

However, this resolver requires jsch and and some other jars. How can I put them on the project's build classpath so that ivy will use them?

This is my BuildConfig.groovy

grails.project.class.dir = "target/classes"
grails.project.test.class.dir = "target/test-classes"
grails.project.test.reports.dir = "target/test-reports"
grails.project.war.file = "target/${appName}-${appVersion}.war"

//Configure resolver
def sshResolver = new org.apache.ivy.plugins.resolver.SshResolver()
['libraries', 'builds'].each {
    sshResolver.addArtifactPattern("/home/ivy/[organisation]/[revision]/[artifact].[ext]")
    sshResolver.addIvyPattern("/home/ivy/[organisation]/[revision]/[artifact].[ext]")
}
sshResolver.name = "ssh"
sshResolver.settings = ivySettings

resolver sshResolver

grails.project.dependency.resolution = {
    // inherit Grails' default dependencies
    inherits("global") {
    }
    log "warn" 
    repositories {
        grailsPlugins()
        grailsHome()
        grailsCentral()
        ssh()
    }
    dependencies {
        compile 'someorg:somejar:1.0'
        runtime 'mysql:mysql-connector-java:5.1.13'
    }   
}

回答1:


I had the same problem and got this answer from the Ian Roberts on the Grails user list which works for me:

def myCL = new URLClassLoader([new File(
            "${basedir}/lib/the.jar"
        ).toURI().toURL()] as URL[],
        org.apache.ivy.plugins.repository.AbstractRepository.classLoader)
resolver myCL.loadClass('com.whatever.MyResolver').newInstance()

Passing the class loader that loaded Ivy as the parent is important so that it can resolve Ivy classes.

If you need to load multiple jars (because the class you are loading depends on them), then put all the files in the list like so:

def myCL = new URLClassLoader([
        "${basedir}/lib/jar1",
        "${basedir}/lib/jar2", // etc.
    ].collect { new File(it).toURI().toURL() } as URL[],
    org.apache.ivy.plugins.repository.AbstractRepository.classLoader)
resolver myCL.loadClass('com.whatever.MyResolver').newInstance()



回答2:


Another option that seems to work is to use @Grab. Something like:

@Grab(group="com.jcraft",module="jsch",version="0.1.42")
import org.apache.ivy.plugins.resolver.SshResolver

def sshResolver = new SshResolver()
['libraries', 'builds'].each {
    sshResolver.addArtifactPattern("/home/ivy/[organisation]/[revision]/[artifact].[ext]")
    sshResolver.addIvyPattern("/home/ivy/[organisation]/[revision]/[artifact].[ext]")
}
sshResolver.name = "ssh"
sshResolver.settings = ivySettings

resolver sshResolver

If your jar isn't in a public repository, it may be a little trickier.




回答3:


Grails uses ivy to implement it's dependency management. All you should need to do is declare the extra libraries you need. Have you tried something like this:

dependencies {
    ..
    compile 'com.jcraft:jsch:0.1.42'
    ..
}   



回答4:


Apparently

grails -cp ./lib/jsch.jar 

was the answer, not the -classpath or --classpath that I had initially tried.

If anyone has a better answer I will certainly accept it over mine.

I tried placing the jar in grails/lib but it gets loaded after the resolvers are processed.

I tried this in PreInit.groovy but no luck there either.

grails.compiler.dependencies = { fileset(file:'${basedir}/lib/jsch.jar') } 


来源:https://stackoverflow.com/questions/3999057/in-grails-how-do-i-specify-jars-needed-by-an-ivy-resolver

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!