Gradle - 同一个库的 2 个不同版本

Gradle - 2 Different versions of the same library

我正在使用 Gradle 构建一个使用 Hadoop 和 Jetty 的项目。我使用与 Java Servlets 3.0 兼容的较新版本的 Jetty。

Hadoop 似乎使用与 Java Servlets 3.0 兼容的旧版 Jetty。

当我尝试 运行 Web 服务器上的某些方法时,抛出 NoSuchMethodError。我相信这是因为正在使用旧版本的 Servlets api。

理想情况下,我想指定 Hadoop 使用的 Jetty 依赖于 servlet API 2.5,而我的 Jetty 服务器使用 3.0。

如果这不可能,我想指定两者都使用 3.0。

我的全部 build.gradle:

        apply plugin: 'java'

    sourceCompatibility = 1.8
    version = '1.0'

    repositories {
        mavenCentral()
        jcenter() // for a solr dependency
    }

dependencies {
    //testCompile group: 'junit', name: 'junit', version: '4.11'


    compile group: 'org.eclipse.jetty.aggregate', name:'jetty-all-server', version:'8.1.16.v20140903'

    compile group:'org.codehaus.jackson', name:'jackson-core-asl',version: '1.9.13'
    compile group:'org.codehaus.jackson', name:'jackson-mapper-asl',version: '1.9.13'
    compile group:'org.apache.commons', name: 'commons-csv', version: '1.1'

    compile group:'org.apache.lucene', name:'lucene-core', version:'5.0.0'
    compile group:'org.apache.solr', name: 'solr-core', version:'5.0.0'

    compile group:'org.apache.hadoop', name:'hadoop-core', version:'1.2.1'

    compile group:'javax.servlet', name:'javax.servlet-api', version:'3.0.1'
}

project.getConfigurations().all { config->
    config.resolutionStrategy.eachDependency
                        {DependencyResolveDetails details->

                            if (details.requested.group == 'org.mortbay.jetty' && details.requested.name == "servlet-api")
                            {
                                details.requested.group="javax.servlet"
                                details.requested.name="javax.servlet-api"
                                details.requested.version="3.0.1"
                                System.out.println(details.requested.properties);
                            }
                        }
}

jar
        {
            doFirst
                    {



                        def serviceDir = file("$buildDir/META-INF/services")
                        serviceDir.deleteDir()
                        serviceDir.mkdirs()

                        for (file in configurations.runtime){
                            zipTree(file).matching{ include 'META-INF/services/*'}.each {
                                f-> new File(serviceDir, f.name) <<f.getText("UTF-8")
                            }
                        }
                    }

            manifest
                    {
                        attributes 'Main-Class': 'Main'
                    }

            from (configurations.compile.collect {it.isDirectory() ?it:zipTree(it) })
                    {
                        exclude 'META-INF/**'
                    }


            from fileTree(buildDir).matching{ include 'META-INF/services/*'}
        }

清理你的 build.gradle:

apply plugin: 'java'

sourceCompatibility = JavaVersion.VERSION_1_8
version = '1.0'

repositories {
    jcenter()
}

dependencies {
    compile 'org.eclipse.jetty.aggregate:jetty-all-server:8.1.16.v20140903'
    compile 'org.codehaus.jackson:jackson-core-asl:1.9.13'
    compile 'org.codehaus.jackson:jackson-mapper-asl:1.9.13'
    compile 'org.apache.commons:commons-csv:1.1'
    compile 'org.apache.lucene:lucene-core:5.0.0'
    compile 'org.apache.solr:solr-core:5.0.0'
    compile 'org.apache.hadoop:hadoop-core:1.2.1'
    compile 'javax.servlet:javax.servlet-api:3.0.1'
}

检查jetty配置:

javax.servlet.http.HttpServletRequest.getParts() 仅适用于 Servlet API 3.0

要检查的事项:

  • 确定你是 运行 Jetty 8 或 Jetty 9
  • 确保您的 WEB-INF/web.xml 配置为使用 Servlet API 3.0
  • 确保您的构建工具使用的是 servlet-api 3.0 jar。
  • 确保您的 WEB-INF/lib 目录中有相同的 servlet api 3.0 jar。

来源:

我最终不得不从 hadoop exclude tomcat 将旧项目放入 class 路径。这是有效的,因为我没有使用 tomcat 正在使用的任何功能。该解决方案适用于我的情况,但我仍然想知道如果您需要同一个库的 2 个(不兼容)版本并且不能排除任何一个版本,该怎么办。