【问题标题】:In Grails, how do I specify jars needed by an ivy resolver?在 Grails 中,如何指定 ivy 解析器所需的 jars?
【发布时间】:2011-04-29 06:46:39
【问题描述】:

在一个 grails 项目中,我根据参考文档 http://www.grails.org/doc/latest/guide/single.html#12.2%20Plugin%20Repositories 添加了一个自定义的 ivy 解析器。

但是,此解析器需要 jsch 和其他一些 jar。如何将它们放在项目的构建类路径中以便 ivy 使用它们?

这是我的 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'
    }   
}

【问题讨论】:

    标签: grails ivy resolver


    【解决方案1】:

    我遇到了同样的问题,我从 Grails 用户列表中的 Ian Roberts 那里得到了这个答案,这对我有用:

    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()
    

    传递加载 Ivy 作为父类的类加载器很重要,这样它就可以解析 Ivy 类。

    如果你需要加载多个 jars(因为你要加载的类依赖于它们),那么将所有文件放在列表中,如下所示:

    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()
    

    【讨论】:

    • 这很聪明。不幸的是,我仍然得到 java.lang.ClassNotFoundException: com.jcraft.jsch.JSchException with def myCL = new URLClassLoader([new File( "${basedir}/lib/jsch-0.1.31.jar" ).toURI()。 toURL()] as URL[], org.apache.ivy.plugins.repository.AbstractRepository.classLoader) 解析器 myCL.loadClass('org.apache.ivy.plugins.resolver.SshResolver').newInstance() 哦好吧。好在我切换到了常规的 Maven 存储库。
    • @gabe,您需要将所有必需的 jar 添加到列表中。我会为多个 jar 更新它。
    【解决方案2】:

    另一个似乎可行的选项是使用@Grab。比如:

    @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
    

    如果您的 jar 不在公共存储库中,则可能会有点棘手。

    【讨论】:

      【解决方案3】:

      Grails 使用 ivy 来实现它的依赖管理。您需要做的就是声明您需要的额外库。你有没有尝试过这样的事情:

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

      【讨论】:

      • 我尝试构建 'com.jcraft:jsch:0.1.42' 不幸的是,它不是项目的依赖项,而是解析器的依赖项。所以我在处理依赖项之前得到了错误。
      【解决方案4】:

      显然

      grails -cp ./lib/jsch.jar 
      

      是答案,而不是我最初尝试的 -classpath 或 --classpath。

      如果有人有更好的答案,我肯定会接受。

      我尝试将 jar 放在 grails/lib 中,但它在解析器处理完毕后被加载。

      我在 PreInit.groovy 中尝试过,但也没有运气。

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

      【讨论】:

        猜你喜欢
        • 2013-02-07
        • 2013-08-21
        • 2012-12-31
        • 1970-01-01
        • 2013-09-24
        • 1970-01-01
        • 2016-08-24
        • 2010-12-07
        • 2013-02-04
        相关资源
        最近更新 更多