fdsa
fdsa

Reputation: 1409

Gradle - 2 Different versions of the same library

I am using Gradle to build a project that uses Hadoop and Jetty. I use a newer version of Jetty that is compatible with Java Servlets 3.0.

Hadoop appears to use an older version of Jetty that is compatible with Java Servlets 3.0.

When I attempt to run certain methods on the web server, a NoSuchMethodError is thrown. I believe this is because an older version of the Servlets api is being used.

Ideally, I would like to specify that the Jetty that Hadoop uses has the dependency on servlets API 2.5 and my Jetty server uses 3.0.

If this is not possible, I would like to specify that both use 3.0.

My entire 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/*'}
        }

Upvotes: 0

Views: 2082

Answers (2)

fdsa
fdsa

Reputation: 1409

I ended up having to exclude tomcat from hadoop which was the thing that was putting the old item in the class path. This worked because I didn't use whatever functionality tomcat was using. This solution worked in my case but I would still like to know what to do if you need 2 (incompatible) versions of the same library and cannot exclude either one.

Upvotes: 0

Jared Burrows
Jared Burrows

Reputation: 55535

Clean your 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'
}

Check jetty configuration:

javax.servlet.http.HttpServletRequest.getParts() is only available starting with Servlet API 3.0

Things to check:

  • Be sure you are running Jetty 8 or Jetty 9
  • Make sure you have your WEB-INF/web.xml configured to use Servlet API 3.0
  • Make sure your build tool is using the servlet-api 3.0 jars.
  • Make sure you have the same servlet api 3.0 jar in your WEB-INF/lib directory.

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

Upvotes: 1

Related Questions