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

时间:2015-04-22 21:45:23

标签: java servlets gradle

我正在使用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/*'}
        }

2 个答案:

答案 0 :(得分:1)

清理您的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。

来源:Facing java.lang.NoSuchMethodError: HttpServletRequest.getParts()Ljava/util/Collection

答案 1 :(得分:0)

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