Reputation: 1409
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
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
Reputation: 55535
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
configuration:javax.servlet.http.HttpServletRequest.getParts()
is only available starting with Servlet API 3.0
Things to check:
WEB-INF/web.xml
configured to use Servlet API 3.0WEB-INF/lib
directory.Source: Facing java.lang.NoSuchMethodError: HttpServletRequest.getParts()Ljava/util/Collection
Upvotes: 1