THRIFT-(1418|1507|3983|4120|4178|4259|4294): Multiple issues
Client: java

THRIFT-4294: Java Configure Fails for Ant >= 1.10
THRIFT-4259: Thrift does not compile due to Ant Maven task errors
THRIFT-4178: Java libraries missing from package when using cmake
THRIFT-3983: libthrift is deployed on central with pom packaging
             instead of jar
THRIFT-1507: Maven can't download resource from central when behind
             a proxy and won't use local repository
THRIFT-1418: Compiling Thrift from source: Class
             org.apache.tools.ant.taskdefs.ConditionTask doesn't
             support the nested "typefound" element

Refactor CMake install hook to allow using "sudo make install/fast"
which avoids the THRIFT-1507 and THRIFT-1418 issues.

New Gradle based build system for Thrift Java Library

* Add Gradle 4.4.1 Wrapper artifacts to enable builds
Using the Gradle Wrapper helps normalize the builds on all platforms
so we use a consistent build tool independent of package managers.

The Gradle build logic was partitioned into multiple specific
scripts to simplify understanding and maintenance of the build.

This is now hooked into CMake and Autoconf processing steps
and can build/test/publish to Maven. The README.md was updated
to illustrate the new build options and add some documentation
on the requirements for Maven publication.

Cleaned up the CMake files to reduce reliance on file globbing
which is known to cause confusion when multiple users contribute.

* Fix two minor issues in Javadoc and unit test

Return values were undeclared in Javadoc
Test was asserting on the wrong test object instance

* Create simple runner scripts for cross-check

Using Gradle as a java execution wrapper is too heavy.
I simplified the test client/server execution by using a
three generated scripts in the build directory direcly
callable by the cross-check test harness.

* Cleanup the remaining Ant build scripts

Pulled the Maven Ant task properties out of the Java build
since they are no longer used there.
Deleted the no longer used build.xml and build.properties
files from the Java build.
Made each Ant build own the Maven Ant task details in their
build.properties file.

* Fix the build issue with Java SSL in the ubuntu-trusty container

The latest Trusty JDK7 builds seem to have encountered this issue
because the OpenJDK removed the SunEC algorithms.

* Update the developer info as requested in review

Use the generic Apache Thrift developer list for contact information

* Add Clover Code coverage for easy access by developers

Clover plugin for Gradle was applied and configured which enables
code coverage reports to be available on demand via a command line
option. The documentation in the README.md was enhanced to give
the details of this change and how to take advantage of it.
diff --git a/lib/as3/build.properties b/lib/as3/build.properties
new file mode 100644
index 0000000..8463668
--- /dev/null
+++ b/lib/as3/build.properties
@@ -0,0 +1,5 @@
+# Maven Ant tasks Jar details
+mvn.ant.task.version=2.1.3
+mvn.repo=http://repo1.maven.org/maven2
+mvn.ant.task.url=${mvn.repo}/org/apache/maven/maven-ant-tasks/${mvn.ant.task.version}
+mvn.ant.task.jar=maven-ant-tasks-${mvn.ant.task.version}.jar
diff --git a/lib/as3/build.xml b/lib/as3/build.xml
index 604da42..2b374dd 100755
--- a/lib/as3/build.xml
+++ b/lib/as3/build.xml
@@ -7,9 +7,9 @@
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License. You may obtain a copy of the License at
- 
+
  http://www.apache.org/licenses/LICENSE-2.0
- 
+
  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -19,23 +19,24 @@
  -->
 <project name="libthrift-as3" default="compile" basedir="."
   xmlns:artifact="antlib:org.apache.maven.artifact.ant">
-	
+
   <property name="as3.artifactid" value="${ant.project.name}"/>
-	
+
   <property name="thrift.root" location="${basedir}/../../"/>
   <property name="thrift.java.dir" location="${thrift.root}/lib/java"/>
   <property name="build.tools.dir" location="${thrift.java.dir}/build/tools/"/>
-  <property name="thrift_compiler" value="${thrift.root}/compiler/cpp/thrift"/> 
+  <property name="thrift_compiler" value="${thrift.root}/compiler/cpp/thrift"/>
+  <property file="${basedir}/build.properties"/>
 
   <!-- inherit from the java build file for version and other properties -->
-  <property file="${thrift.java.dir}/build.properties" />
+  <property file="${thrift.java.dir}/gradle.properties" />
 
   <property environment="env"/>
 
   <condition property="version" value="${thrift.version}">
     <isset property="release"/>
   </condition>
-  <property name="version" value="${thrift.version}-snapshot"/>
+  <property name="version" value="${thrift.version}-SNAPSHOT"/>
 
   <property name="as3.final.name" value="${as3.artifactid}-${version}"/>
 
@@ -52,12 +53,13 @@
   <target name="setup.init">
     <tstamp/>
     <mkdir dir="${build.dir}"/>
+    <mkdir dir="${build.tools.dir}"/>
   </target>
 
   <target name="flex.check" unless="FLEX_HOME">
     <fail message='You must set the FLEX_HOME property pointing to your flex SDK, eg. ant -DFLEX_HOME="/Applications/Adobe Flex Builder 3/sdks/3.2.0"'/>
   </target>
-	
+
   <target name="flex.init" depends="flex.check" unless="flex.finished">
     <taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" />
     <property name="flex.finished" value="true"/>
@@ -69,10 +71,10 @@
         <include name="**/*.as"/>
       </fileset>
     </path>
-    <pathconvert 
-      property="as.src.classes" 
-      pathsep=" " 
-      dirsep="." 
+    <pathconvert
+      property="as.src.classes"
+      pathsep=" "
+      dirsep="."
       refid="as.src.files"
     >
       <map from="${src}/" to=""/>
@@ -108,19 +110,19 @@
     <artifact:remoteRepository id="apache" url="${apache.repo}"/>
 
     <!-- Pom file information -->
-    <artifact:pom id="pom" 
-      groupId="${thrift.groupid}" 
+    <artifact:pom id="pom"
+      groupId="${thrift.groupid}"
       artifactId="${as3.artifactid}"
-      version="${version}" 
+      version="${version}"
       url="http://thrift.apache.org"
       name="Apache Thrift"
       description="Thrift is a software framework for scalable cross-language services development."
-      packaging="pom"
+      packaging="swc"
     >
       <remoteRepository refid="central"/>
       <remoteRepository refid="apache"/>
       <license name="The Apache Software License, Version 2.0" url="${license}"/>
-      <scm connection="scm:git:https://git-wip-us.apache.org/repos/asf/thrift.git" 
+      <scm connection="scm:git:https://git-wip-us.apache.org/repos/asf/thrift.git"
       developerConnection="scm:git:https://git-wip-us.apache.org/repos/asf/thrift.git"
       url="https://git-wip-us.apache.org/repos/asf?p=thrift.git"
       />
@@ -176,5 +178,5 @@
     <!-- run with: ant -Drelease=true publish -->
     <signAndDeploy file="${as3.pom.xml}" packaging="pom" classifier="" pom="${as3.pom.xml}"/>
     <signAndDeploy file="${as3.swc.file}" packaging="swc" classifier="" pom="${as3.pom.xml}"/>
-  </target>	
+  </target>
 </project>
diff --git a/lib/java/CMakeLists.txt b/lib/java/CMakeLists.txt
index f7a1a63..46064e6 100644
--- a/lib/java/CMakeLists.txt
+++ b/lib/java/CMakeLists.txt
@@ -17,19 +17,14 @@
 # under the License.
 #
 
-file(GLOB java_sources src/**/*.java)
-
 if(ANDROID)
-    set(android_sources
-        android/build.gradle
-        android/settings.gradle
-        android/src/main/AndroidManifest.xml
-    )
     set(THRIFT_AAR outputs/aar/thrift-debug.aar outputs/aar/thrift-release.aar)
     add_custom_command(
         OUTPUT ${THRIFT_AAR}
-        COMMAND ${GRADLE_EXECUTABLE} -p"${CMAKE_CURRENT_SOURCE_DIR}/android" -PbuildDir="${CMAKE_CURRENT_BINARY_DIR}" assemble
-        DEPENDS ${java_sources} ${android_sources})
+        COMMAND ${GRADLE_EXECUTABLE}
+            -p "${CMAKE_CURRENT_SOURCE_DIR}/android"
+            "-PbuildDir=${CMAKE_CURRENT_BINARY_DIR}/android/build" assemble
+    )
     add_custom_target(thrift_aar ALL DEPENDS ${THRIFT_AAR})
 
 else(ANDROID)
@@ -46,35 +41,47 @@
         set(JAVA_DOC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${DOC_INSTALL_DIR}/java")
     endif()
 
-    file(GLOB_RECURSE ThriftJava_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.java)
-    set(ThriftJava_ARTIFACTS
-        libthrift-${thrift_VERSION}.jar
-        libthrift-${thrift_VERSION}.pom
-    )
-    add_custom_command(
-        OUTPUT ${ThriftJava_ARTIFACTS}
-        COMMAND ${Ant_EXECUTABLE} ${ANT_FLAGS} -Dbuild.dir="${CMAKE_CURRENT_BINARY_DIR}" -f build.xml
-        MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/build.xml
-        DEPENDS ${ThriftJava_SOURCES}
-        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    )
-
     add_custom_target(ThriftJava ALL
-        COMMENT "Building Java library using Ant"
-        DEPENDS ${ThriftJava_ARTIFACTS}
+        COMMENT "Building Java library using Gradle Wrapper"
+        COMMAND ${GRADLEW_EXECUTABLE} ${GRADLE_OPTS} assemble
+            --console=plain --no-daemon
+            -Prelease=true
+            -Pthrift.version=${thrift_VERSION}
+            "-Pbuild.dir=${CMAKE_CURRENT_BINARY_DIR}/build"
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
     )
 
-    # Hook the ant install task into CMake install
-    install(CODE "execute_process(
-        COMMAND ${Ant_EXECUTABLE} ${ANT_FLAGS} install
-        -Dbuild.dir=\"${CMAKE_CURRENT_BINARY_DIR}\"
-        -Dinstall.path=\"${JAVA_INSTALL_DIR}\" -Dinstall.javadoc.path=\"${JAVA_DOC_INSTALL_DIR}\" -f build.xml
+    # Enable publishing from CMake if the publishing information is provided
+    add_custom_target(MavenPublish
+        COMMENT "Publishing Java Library to Apache Maven staging"
+        COMMAND ${GRADLEW_EXECUTABLE} ${GRADLE_OPTS} clean uploadArchives
+            --console=plain --no-daemon
+            -Prelease=true
+            -Pthrift.version=${thrift_VERSION}
+            "-Pbuild.dir=${CMAKE_CURRENT_BINARY_DIR}/build"
         WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    )")
+    )
+
+    # Hook the CMake install process to the results from make ALL.
+    # This works best when 'make all && sudo make install/fast' is used.
+    # Using slash to end the source location to avoid copying the directory path.
+    install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build/libs/
+            DESTINATION ${JAVA_INSTALL_DIR}
+            FILES_MATCHING PATTERN "libthrift-${thrift_VERSION}.jar")
+    install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build/deps/
+            DESTINATION ${JAVA_INSTALL_DIR}
+            FILES_MATCHING PATTERN "*.jar")
+    install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build/docs/javadoc/
+            DESTINATION ${JAVA_DOC_INSTALL_DIR})
 
     if(BUILD_TESTING)
         add_test(NAME JavaTest
-                 COMMAND ${Ant_EXECUTABLE} ${ANT_FLAGS} -Dbuild.dir=${CMAKE_CURRENT_BINARY_DIR} -Dthrift.compiler=${THRIFT_COMPILER} -f build.xml test
-                 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+                COMMAND ${GRADLEW_EXECUTABLE} ${GRADLE_OPTS} test
+                    --console=plain --no-daemon
+                    -Prelease=true
+                    -Pthrift.version=${thrift_VERSION}
+                    "-Pbuild.dir=${CMAKE_CURRENT_BINARY_DIR}/build"
+                    "-Pthrift.compiler=${THRIFT_COMPILER}"
+                WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
     endif()
 endif(ANDROID)
diff --git a/lib/java/Makefile.am b/lib/java/Makefile.am
index 1c867ae..65981ca 100644
--- a/lib/java/Makefile.am
+++ b/lib/java/Makefile.am
@@ -20,29 +20,53 @@
 export CLASSPATH
 
 all-local:
-	$(ANT) $(ANT_FLAGS)
+	./gradlew $(GRADLE_OPTS) assemble \
+		-Prelease=true \
+		-Pthrift.version=$(PACKAGE_VERSION) \
+		--console=plain
 
 install-exec-hook:
-	$(ANT) $(ANT_FLAGS) install -Dinstall.path=$(DESTDIR)$(JAVA_PREFIX) \
-		-Dinstall.javadoc.path=$(DESTDIR)$(docdir)/java
+	./gradlew $(GRADLE_OPTS) install \
+		-Prelease=true \
+		-Pinstall.path=$(DESTDIR)$(JAVA_PREFIX) \
+		-Pinstall.javadoc.path=$(DESTDIR)$(docdir)/java \
+		-Pthrift.version=$(PACKAGE_VERSION) \
+		--console=plain
 
-# Make sure this doesn't fail if ant is not configured.
 clean-local:
-	ANT=$(ANT) ; if test -z "$$ANT" ; then ANT=: ; fi ; \
-	$$ANT $(ANT_FLAGS) clean
+	./gradlew $(GRADLE_OPTS) clean --console=plain
 
 precross: $(THRIFT)
-	$(ANT) $(ANT_FLAGS) compile-test
+	./gradlew $(GRADLE_OPTS) shadowJar \
+		-Prelease=true \
+		-Pthrift.version=$(PACKAGE_VERSION) \
+		-Pthrift.compiler=$(THRIFT) \
+		--console=plain
 
-check-local: all
-	$(ANT) $(ANT_FLAGS) test
+check-local: $(THRIFT)
+	./gradlew $(GRADLE_OPTS) test \
+		-Prelease=true \
+		-Pthrift.version=$(PACKAGE_VERSION) \
+		-Pthrift.compiler=$(THRIFT) \
+		--console=plain
+
+maven-publish:
+	./gradlew $(GRADLE_OPTS) uploadArchives \
+		-Prelease=true \
+		-Pthrift.version=$(PACKAGE_VERSION) \
+		--console=plain
 
 EXTRA_DIST = \
-	build.xml \
-	build.properties \
+	build.gradle \
+	gradle.properties \
+	settings.gradle \
+	gradle \
+	gradlew \
+	gradlew.bat \
 	CMakeLists.txt \
 	coding_standards.md \
 	android \
 	src \
 	test \
+	code_quality_tools \
 	README.md
diff --git a/lib/java/README.md b/lib/java/README.md
index 66bcfa5..1e4aed2 100644
--- a/lib/java/README.md
+++ b/lib/java/README.md
@@ -20,18 +20,59 @@
 specific language governing permissions and limitations
 under the License.
 
-Using Thrift with Java
-======================
+Building and installing from source
+===================================
+
+When using a CMake build from the source distribution on Linux the
+easiest way to build and install is this simple command line:
+
+    make all && sudo make install/fast
+
+It is important to use the install/fast option to eliminate
+the automatic rebuild by dependency that causes issues because
+the build tooling is designed to work with cached files in the
+user home directory during the build process. Instead this builds
+the code in the expected local build tree and then uses CMake
+install code to copy to the target destination.
+
+Building Thrift with Gradle without CMake/Autoconf
+==================================================
 
 The Thrift Java source is not build using the GNU tools, but rather uses
-the Apache Ant build system, which tends to be predominant amongst Java
+the Gradle build system, which tends to be predominant amongst Java
 developers.
 
 To compile the Java Thrift libraries, simply do the following:
 
-    ant
+    ./gradlew
 
-Yep, that's easy. Look for libthrift.jar in the base directory.
+Yep, that's easy. Look for libthrift-<version>.jar in the build/libs directory.
+
+The default build will run the unit tests which expect a usable
+Thrift compiler to exist on the system. You have two choices for
+that.
+
+* Build the Thrift executable from source at the default
+  location in the source tree. The project is configured
+  to look for it there.
+* Install the published binary distribution to have Thrift
+  executable in a known location and add the path to the
+  ~/.gradle/gradle.properties file using the property name
+  "thrift.compiler". For example this would set the path in
+  a Windows box if Thrift was installed under C:\Thrift
+
+    thrift.compiler=C:/Thrift/thrift.exe
+
+To just build the library without running unit tests you simply do this.
+
+    ./gradlew assemble
+
+To install the library in the local Maven repository location
+where other Maven or Gradle builds can reference it simply do this.
+
+    ./gradlew install
+
+The library will be placed in your home directory under .m2/repository
 
 To include Thrift in your applications simply add libthrift.jar to your
 classpath, or install if in your default system classpath of choice.
@@ -39,15 +80,84 @@
 
 Build Thrift behind a proxy:
 
-    ant -Dproxy.enabled=1 -Dproxy.host=myproxyhost -Dproxy.user=thriftuser -Dproxy.pass=topsecret
+    ./gradlew -Dhttp.proxyHost=myproxyhost -Dhttp.proxyPort=8080 -Dhttp.proxyUser=thriftuser -Dhttp.proxyPassword=topsecret
 
 or via
 
-    ./configure --with-java ANT_FLAGS='-Dproxy.enabled=1 -Dproxy.host=myproxyhost -Dproxy.user=thriftuser -Dproxy.pass=topsecret'
+    ./configure --with-java GRADLE_OPTS='-Dhttp.proxyHost=myproxyhost -Dhttp.proxyPort=8080 -Dhttp.proxyUser=thriftuser -Dhttp.proxyPassword=topsecret'
+
+
+Unit Test HTML Reports
+======================
+
+The build will automatically generate an HTML Unit Test report. This can be found
+under build/reports/tests/test/index.html. It can be viewed with a browser
+directly from that location.
+
+
+Clover Code Coverage for Thrift
+===============================
+
+The build will optionally generate Clover Code coverage if the Gradle property
+`cloverEnabled=true` is set in ~/.gradle/gradle.properties or on the command line
+via `-PcloverEnabled=true`. The generated report can be found under the location
+build/reports/clover/html/index.html. It can be viewed with a browser
+directly from that location. Additionally, a PDF report is generated and is found
+under the location build/reports/clover/clover.pdf.
+
+The following command will build, unit test, and generate Clover reports:
+
+    ./gradlew -PcloverEnabled=true
+
+
+Publishing Maven Artifacts to Maven Central
+===========================================
+
+The Automake build generates a Makefile that provides the correct parameters
+when you run the build provided the configure.ac has been set with the correct
+version number. The Gradle build will receive the correct value for the build.
+The same applies to the CMake build, the value from the configure.ac file will
+be used if you execute these commands:
+
+    make maven-publish   -- This is for an Automake Linux build
+    make MavenPublish    -- This is for a CMake generated build
+
+The uploadArchives task in Gradle is preconfigured with all necessary details
+to sign and publish the artifacts from the build to the Apache Maven staging
+repository. The task requires the following externally provided properties to
+authenticate to the repository and sign the artifacts. The preferred approach
+is to create or edit the ~/.gradle/gradle.properties file and add the following
+properties to it.
+
+    # Signing key information for artifacts PGP signature (values are examples)
+    signing.keyId=24875D73
+    signing.password=secret
+    signing.secretKeyRingFile=/Users/me/.gnupg/secring.gpg
+
+    # Apache Maven staging repository user credentials
+    mavenUser=meMyselfAndI
+    mavenPassword=MySuperAwesomeSecretPassword
+
+It is also possible to manually publish using the Gradle build directly.
+With the key information and credentials in place the following will generate
+if needed the build artifacts and proceed to publish the results.
+
+    ./gradlew -Prelease=true -Pthrift.version=0.11.0 uploadArchives
+
+It is also possible to override the target repository for the Maven Publication
+by using a Gradle property, for example you can publish signed JAR files to your
+company internal server if you add this to the command line or in the
+~/.gradle/gradle.properties file. The URL below assumes a Nexus Repository.
+
+    maven-repository-url=https://my.company.com/service/local/staging/deploy/maven2
+
+Or the same on the command line:
+
+    ./gradlew -Pmaven-repository-url=https://my.company.com/service/local/staging/deploy/maven2 -Prelease=true -Pthrift.version=0.11.0 uploadArchives
 
 
 Dependencies
 ============
 
-Apache Ant
-http://ant.apache.org/
+Gradle
+http://gradle.org/
diff --git a/lib/java/android/build.gradle b/lib/java/android/build.gradle
index 4aa2864..c998423 100644
--- a/lib/java/android/build.gradle
+++ b/lib/java/android/build.gradle
@@ -20,31 +20,31 @@
 apply plugin: 'com.android.library'
 
 android {
-  compileSdkVersion 23
-  buildToolsVersion "23.0.1"
-  useLibrary 'org.apache.http.legacy'
-  sourceSets.main.java {
-    srcDir '../src'
-    exclude 'org/apache/thrift/transport/TSaslClientTransport.java'
-    exclude 'org/apache/thrift/transport/TSaslServerTransport.java'
-    exclude 'org/apache/thrift/transport/TSaslTransport.java'
-  }
+    compileSdkVersion 23
+    buildToolsVersion "23.0.1"
+    useLibrary 'org.apache.http.legacy'
+    sourceSets.main.java {
+        srcDir '../src'
+        exclude 'org/apache/thrift/transport/TSaslClientTransport.java'
+        exclude 'org/apache/thrift/transport/TSaslServerTransport.java'
+        exclude 'org/apache/thrift/transport/TSaslTransport.java'
+    }
 }
 
 repositories {
-  mavenCentral()
+    mavenCentral()
 }
 dependencies {
-  compile 'org.slf4j:slf4j-api:1.7.13'
-  compile 'javax.servlet:servlet-api:2.5'
-  compile 'org.apache.httpcomponents:httpcore:4.4.4'
+    compile 'org.slf4j:slf4j-api:1.7.13'
+    compile 'javax.servlet:servlet-api:2.5'
+    compile 'org.apache.httpcomponents:httpcore:4.4.4'
 }
 
 buildscript {
-  repositories {
-    mavenCentral()
-  }
-  dependencies {
-    classpath 'com.android.tools.build:gradle:1.5.0'
-  }
+    repositories {
+        mavenCentral()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:1.5.0'
+    }
 }
diff --git a/lib/java/build.gradle b/lib/java/build.gradle
new file mode 100644
index 0000000..4302f77
--- /dev/null
+++ b/lib/java/build.gradle
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Using the legacy plugin classpath for Clover so it can be loaded optionally
+buildscript {
+    repositories {
+        google()
+        jcenter()
+        gradlePluginPortal()
+    }
+
+    dependencies {
+        classpath 'com.bmuschko:gradle-clover-plugin:2.2.0'
+    }
+}
+
+plugins {
+    id 'java'
+    id 'maven'
+    id 'signing'
+    id 'com.github.johnrengelman.shadow' version '2.0.2'
+}
+
+description = 'Apache Thrift Java Library'
+
+defaultTasks 'build'
+
+// Version components for this project
+group = property('thrift.groupid')
+
+// Drop the -dev suffix, we use the SNAPSHOT suffix for non-release versions
+def parsedVersion = property('thrift.version').toString().replace('-dev', '')
+if (Boolean.parseBoolean(project.release)) {
+    version = parsedVersion
+} else {
+    version = parsedVersion + '-SNAPSHOT'
+}
+
+// Keeping the rest of the build logic in functional named scripts for clarity
+apply from: 'gradle/environment.gradle'
+apply from: 'gradle/sourceConfiguration.gradle'
+apply from: 'gradle/additionalArtifacts.gradle'
+apply from: 'gradle/generateTestThrift.gradle'
+apply from: 'gradle/unitTests.gradle'
+apply from: 'gradle/cloverCoverage.gradle'
+apply from: 'gradle/functionalTests.gradle'
+apply from: 'gradle/publishing.gradle'
+apply from: 'gradle/codeQualityChecks.gradle'
diff --git a/lib/java/build.properties b/lib/java/build.properties
deleted file mode 100644
index 96cf8d3..0000000
--- a/lib/java/build.properties
+++ /dev/null
@@ -1,31 +0,0 @@
-thrift.version=1.0.0
-thrift.groupid=org.apache.thrift
-release=false
-
-# Jar Versions 
-mvn.ant.task.version=2.1.3
-
-# Local Install paths
-install.path=/usr/local/lib
-install.javadoc.path=${install.path}
-
-# Maven dependency download locations
-mvn.repo=http://repo1.maven.org/maven2
-apache.repo=https://repository.apache.org/content/repositories/releases
-mvn.ant.task.url=${mvn.repo}/org/apache/maven/maven-ant-tasks/${mvn.ant.task.version}
-mvn.ant.task.jar=maven-ant-tasks-${mvn.ant.task.version}.jar
-
-# Apache Maven publish 
-license=http://www.apache.org/licenses/LICENSE-2.0.txt
-maven-repository-url=https://repository.apache.org/service/local/staging/deploy/maven2
-maven-repository-id=apache.releases.https
-
-# Jar Versions 
-mvn.ant.task.version=2.1.3
-
-# Dependency versions
-httpclient.version=4.4.1
-httpcore.version=4.4.1
-slf4j.version=1.7.12
-servlet.version=2.5
-
diff --git a/lib/java/build.xml b/lib/java/build.xml
deleted file mode 100644
index d1574af..0000000
--- a/lib/java/build.xml
+++ /dev/null
@@ -1,421 +0,0 @@
-<?xml version="1.0"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- -->
-<project name="libthrift" default="dist" basedir="."
-  xmlns:artifact="antlib:org.apache.maven.artifact.ant">
-
-  <description>Thrift Build File</description>
-  <property name="thrift.root" location="../../"/>
-  <property name="thrift.artifactid" value="libthrift"/>
-
-  <!-- Include the base properties file -->
-  <property file="${basedir}/build.properties" />
-
-  <property environment="env"/>
-
-  <condition property="version" value="${thrift.version}">
-    <isset property="release"/>
-  </condition>
-  <property name="version" value="${thrift.version}-snapshot"/>
-
-  <property name="final.name" value="${thrift.artifactid}-${version}"/>
-
-  <property name="thrift.compiler" location="../../compiler/cpp/thrift"/>
-  <property name="src" location="${basedir}/src"/>
-  <property name="build.dir" location="${basedir}/build"/>
-  <property name="build.lib.dir" location="${build.dir}/lib"/>
-  <property name="build.tools.dir" location="${build.dir}/tools"/>
-  <property name="src.test" location="test"/>
-  <property name="javadoc.dir" location="${build.dir}/javadoc"/>
-  <property name="build.test.dir" location="${build.dir}/test"/>
-  <property name="test.thrift.home" location="${thrift.root}/test"/>
-
-  <property name="gen" location="gen-java"/>
-  <property name="genbean" location="gen-javabean"/>
-  <property name="genreuse" location="gen-javareuse"/>
-  <property name="genfullcamel" location="gen-fullcamel"/>
-
-  <property name="jar.file" location="${build.dir}/${final.name}.jar"/>
-  <property name="test.jar.file" location="${build.dir}/${final.name}-test.jar"/>
-  <property name="javadoc.jar.file" location="${build.dir}/${final.name}-javadoc.jar"/>
-  <property name="source.jar.file" location="${build.dir}/${final.name}-sources.jar"/>
-
-  <!-- Junit properties -->
-  <property name="test.junit.output.format" value="plain"/>
-  <property name="test.timeout" value="2000000"/>
-  <property name="test.src.dir" location="${basedir}/test"/>
-  <property name="test.log.dir" value="${build.test.dir}/log"/>
-  <property name="test.port" value="9090"/>
-
-  <!-- maven properties -->
-  <property name="pom.xml" location="${build.dir}/${final.name}.pom"/>
-
-  <path id="compile.classpath">
-    <fileset dir="${build.lib.dir}">
-      <include name="**/*.jar"/>
-    </fileset>
-  </path>
-
-  <path id="test.classpath">
-    <path refid="compile.classpath"/>
-    <pathelement path="${env.CLASSPATH}"/>
-    <pathelement location="${build.test.dir}"/>
-    <pathelement location="${jar.file}"/>
-    <pathelement location="${test.jar.file}"/>
-
-  </path>
-
-  <!-- Tasks -->
-  <target name="init" depends="setup.init,mvn.init" unless="init.finished">
-    <property name="init.finished" value="true"/>
-  </target>
-
-  <target name="setup.init">
-    <tstamp/>
-    <mkdir dir="${build.dir}"/>
-    <mkdir dir="${build.lib.dir}"/>
-    <mkdir dir="${build.tools.dir}"/>
-    <mkdir dir="${build.test.dir}"/>
-  </target>
-
-  <target name="compile" depends="init">
-    <javac compiler="modern" srcdir="${src}" destdir="${build.dir}" source="1.5" target="1.5"
-    debug="true" classpathref="compile.classpath" includeantruntime="false" encoding="UTF-8">
-      <compilerarg value="-Xlint:unchecked"/>
-    </javac>
-  </target>
-
-  <target name="javadoc" depends="init">
-    <javadoc sourcepath="${src}" destdir="${javadoc.dir}"
-      version="true" windowtitle="Thrift Java API" doctitle="Thrift Java API"
-      classpathref="test.classpath">
-    </javadoc>
-    <jar jarfile="${javadoc.jar.file}" basedir="${javadoc.dir}">
-      <manifest>
-        <attribute name="Implementation-Version" value="${version}"/>
-      </manifest>
-    </jar>
-  </target>
-
-  <target name="dist" depends="compile">
-    <mkdir dir="${build.dir}/META-INF"/>
-    <copy file="${thrift.root}/LICENSE" tofile="${build.dir}/META-INF/LICENSE.txt"/>
-    <copy file="${thrift.root}/NOTICE" tofile="${build.dir}/META-INF/NOTICE.txt"/>
-    <jar jarfile="${jar.file}">
-      <manifest>
-        <attribute name="Implementation-Version" value="${version}"/>
-        <attribute name="Bundle-ManifestVersion" value="2"/>
-        <attribute name="Bundle-SymbolicName" value="${thrift.groupid}"/>
-        <attribute name="Bundle-Name" value="Apache Thrift"/>
-        <attribute name="Bundle-Version" value="${version}"/>
-        <attribute name="Bundle-Description" value="Apache Thrift library"/>
-        <attribute name="Bundle-License" value="${license}"/>
-        <attribute name="Bundle-ActivationPolicy" value="lazy"/>
-        <attribute name="Export-Package" value="${thrift.groupid}.async;uses:=&quot;${thrift.groupid}.protocol,${thrift.groupid}.transport,org.slf4j,${thrift.groupid}&quot;;version=&quot;${version}&quot;,${thrift.groupid}.protocol;uses:=&quot;${thrift.groupid}.transport,${thrift.groupid},${thrift.groupid}.scheme&quot;;version=&quot;${version}&quot;,${thrift.groupid}.server;uses:=&quot;${thrift.groupid}.transport,${thrift.groupid}.protocol,${thrift.groupid},org.slf4j,javax.servlet,javax.servlet.http&quot;;version=&quot;${version}&quot;,${thrift.groupid}.transport;uses:=&quot;${thrift.groupid}.protocol,${thrift.groupid},org.apache.http.client,org.apache.http.params,org.apache.http.entity,org.apache.http.client.methods,org.apache.http,org.slf4j,javax.net.ssl,javax.net,javax.security.sasl,javax.security.auth.callback&quot;;version=&quot;${version}&quot;,${thrift.groupid};uses:=&quot;${thrift.groupid}.protocol,${thrift.groupid}.async,${thrift.groupid}.server,${thrift.groupid}.transport,org.slf4j,org.apache.log4j,${thrift.groupid}.scheme&quot;;version=&quot;${version}&quot;,${thrift.groupid}.meta_data;uses:=&quot;${thrift.groupid}&quot;;version=&quot;${version}&quot;,${thrift.groupid}.scheme;uses:=&quot;${thrift.groupid}.protocol,${thrift.groupid}&quot;;version=&quot;${version}&quot;"/>
-       <attribute name="Import-Package" value="javax.net,javax.net.ssl,javax.security.auth.callback,javax.security.sasl,javax.servlet;resolution:=optional,javax.servlet.http;resolution:=optional,org.slf4j;resolution:=optional;version=&quot;[1.4,2)&quot;,org.apache.http.client;resolution:=optional,org.apache.http.params;resolution:=optional,org.apache.http.entity;resolution:=optional,org.apache.http.client.methods;resolution:=optional,org.apache.http;resolution:=optional"/>
-      </manifest>
-      <fileset dir="${build.dir}">
-        <include name="org/apache/thrift/**/*.class"/>
-        <include name="META-INF/*.txt"/>
-      </fileset>
-    </jar>
-  </target>
-
-  <target name="pack.src">
-    <jar jarfile="${source.jar.file}">
-      <fileset dir="${src}">
-        <include name="**/*.java"/>
-      </fileset>
-    </jar>
-  </target>
-
-  <target name="install" depends="dist,javadoc">
-    <copy todir="${install.path}">
-      <fileset dir="${build.dir}" includes="*.jar"/>
-      <fileset dir="${build.lib.dir}" includes="*.jar"/>
-    </copy>
-    <copy todir="${install.javadoc.path}">
-      <fileset dir="${javadoc.dir}" includes="**/*"/>
-    </copy>
-  </target>
-
-  <target name="clean">
-    <delete dir="${build.dir}"/>
-    <delete dir="${gen}"/>
-    <delete dir="${genbean}"/>
-    <delete dir="${genreuse}"/>
-    <delete dir="${genfullcamel}"/>
-  </target>
-
-  <target name="optional-generate" unless="no-gen-thrift">
-    <antcall target="generate">
-    </antcall>
-  </target>
-
-  <target name="compile-test" description="Build the test suite classes" depends="optional-generate,dist">
-    <javac compiler="modern" debug="true" srcdir="${gen}" destdir="${build.test.dir}" classpathref="test.classpath" includeantruntime="false" encoding="UTF-8">
-      <compilerarg value="-Xlint:deprecation"/>
-      <!--<compilerarg value="-Xlint:unchecked"/>-->
-    </javac>
-    <javac compiler="modern" debug="true" srcdir="${genbean}" destdir="${build.test.dir}" classpathref="test.classpath" includeantruntime="false" encoding="UTF-8">
-      <compilerarg value="-Xlint:deprecation"/>
-      <!--<compilerarg value="-Xlint:unchecked"/>-->
-    </javac>
-    <javac compiler="modern" debug="true" srcdir="${genreuse}" destdir="${build.test.dir}" classpathref="test.classpath" includeantruntime="false" encoding="UTF-8">
-      <compilerarg value="-Xlint:deprecation"/>
-      <!--<compilerarg value="-Xlint:unchecked"/>-->
-    </javac>
-    <javac compiler="modern" debug="true" srcdir="${genfullcamel}" destdir="${build.test.dir}" classpathref="test.classpath" includeantruntime="false" encoding="UTF-8">
-      <compilerarg value="-Xlint:deprecation"/>
-      <!--<compilerarg value="-Xlint:unchecked"/>-->
-    </javac>
-    <javac compiler="modern" debug="true" srcdir="${src.test}" destdir="${build.test.dir}" classpathref="test.classpath" includeantruntime="false" encoding="UTF-8">
-      <compilerarg value="-Xlint:deprecation"/>
-      <!--<compilerarg value="-Xlint:unchecked"/>-->
-    </javac>
-    <copy todir="${build.test.dir}">
-      <fileset dir="${src.test}" includes="log4j.properties"/>
-    </copy>
-    <jar jarfile="${test.jar.file}" basedir="${build.test.dir}"/>
-  </target>
-
-  <target name="junit-test" description="Run the JUnit test suite" depends="compile-test">
-    <mkdir dir="${test.log.dir}"/>
-    <junit printsummary="true" showoutput="${test.output}" timeout="${test.timeout}"
-      haltonfailure="true" errorProperty="tests.failed" failureProperty="tests.failed"
-      fork="true" forkmode="perTest" maxmemory="512m"
-    >
-      <sysproperty key="build.test" value="${build.test.dir}"/>
-      <sysproperty key="test.port" value="${test.port}"/>
-      <sysproperty key="javax.net.ssl.trustStore" value="${src.test}/.truststore"/>
-      <sysproperty key="javax.net.ssl.trustStorePassword" value="thrift"/>
-      <sysproperty key="javax.net.ssl.keyStore" value="${src.test}/.keystore"/>
-      <sysproperty key="javax.net.ssl.keyStorePassword" value="thrift"/>
-      <classpath refid="test.classpath"/>
-      <formatter type="${test.junit.output.format}"/>
-      <batchtest todir="${test.log.dir}" unless="testcase">
-        <fileset dir="${test.src.dir}">
-          <include name="**/Test*.java"/>
-          <exclude name="**/TestClient.java"/>
-          <exclude name="**/TestServer.java"/>
-          <exclude name="**/TestNonblockingServer.java"/>
-        </fileset>
-      </batchtest>
-      <batchtest todir="${test.log.dir}" if="testcase">
-        <fileset dir="${test.src.dir}" includes="**/${testcase}.java"/>
-      </batchtest>
-    </junit>
-    <fail if="tests.failed">Tests failed!</fail>
-  </target>
-
-  <target name="deprecated-test" description="Run the non-JUnit test suite" depends="compile-test">
-    <java classname="org.apache.thrift.test.EqualityTest" classpathref="test.classpath" failonerror="true"/>
-    <java classname="org.apache.thrift.test.JavaBeansTest" classpathref="test.classpath" failonerror="true"/>
-  </target>
-
-  <target name="test" description="Run the full test suite" depends="junit-test,deprecated-test"/>
-
-  <target name="testclient" description="Run a test client" depends="compile-test, run-testclient"/>
-  <target name="run-testclient" description="Run a test client">
-    <java classname="org.apache.thrift.test.TestClient"
-      classpathref="test.classpath" failonerror="true" fork="true">
-      <sysproperty key="javax.net.ssl.trustStore" value="${src.test}/.truststore"/>
-      <sysproperty key="javax.net.ssl.trustStorePassword" value="thrift"/>
-      <arg line="${testargs}"/>
-    </java>
-  </target>
-
-  <target name="testserver" description="Run a test server" depends="compile-test, run-testserver"/>
-  <target name="run-testserver" description="Run a test server">
-    <java classname="org.apache.thrift.test.TestServer"
-      classpathref="test.classpath" failonerror="true" fork="true">
-      <sysproperty key="javax.net.ssl.keyStore" value="${src.test}/.keystore"/>
-      <sysproperty key="javax.net.ssl.keyStorePassword" value="thrift"/>
-      <arg line="${testargs}"/>
-    </java>
-  </target>
-
-  <target name="testnonblockingserver" description="Run a test nonblocking server" depends="compile-test, run-testnonblockingserver"/>
-  <target name="run-testnonblockingserver" description="Run a test nonblocking server">
-    <java classname="org.apache.thrift.test.TestNonblockingServer"
-      classpathref="test.classpath" failonerror="true">
-      <arg line="${testargs}"/>
-    </java>
-  </target>
-
-  <target name="generate">
-    <!-- Generate the thrift gen-java source -->
-    <exec executable="${thrift.compiler}" failonerror="true">
-      <arg line="--gen java ${test.thrift.home}/ThriftTest.thrift"/>
-    </exec>
-    <exec executable="${thrift.compiler}" failonerror="true">
-      <arg line="--gen java ${test.thrift.home}/JavaTypes.thrift"/>
-    </exec>
-    <exec executable="${thrift.compiler}" failonerror="true">
-      <arg line="--gen java ${test.thrift.home}/DebugProtoTest.thrift"/>
-    </exec>
-    <exec executable="${thrift.compiler}" failonerror="true">
-      <arg line="--gen java ${test.thrift.home}/OptionalRequiredTest.thrift"/>
-    </exec>
-    <exec executable="${thrift.compiler}" failonerror="true">
-      <arg line="--gen java:beans,nocamel ${test.thrift.home}/JavaBeansTest.thrift"/>
-    </exec>
-    <exec executable="${thrift.compiler}" failonerror="true">
-      <arg line="--gen java ${test.thrift.home}/ManyOptionals.thrift"/>
-    </exec>
-  	<mkdir dir="${genfullcamel}"/>
-    <exec executable="${thrift.compiler}" failonerror="true">
-      <arg line="--gen java:fullcamel -out ${genfullcamel} ${test.thrift.home}/FullCamelTest.thrift"/>
-    </exec>
-  	<mkdir dir="${genreuse}"/>
-    <exec executable="${thrift.compiler}" failonerror="true">
-      <arg line="--gen java:reuse-objects -out ${genreuse} ${test.thrift.home}/ReuseObjects.thrift"/>
-    </exec>
-    <exec executable="${thrift.compiler}" failonerror="true">
-      <arg line="--gen java ${test.thrift.home}/JavaDeepCopyTest.thrift"/>
-    </exec>
-    <exec executable="${thrift.compiler}" failonerror="true">
-      <arg line="--gen java ${test.thrift.home}/EnumContainersTest.thrift"/>
-    </exec>
-  </target>
-
-  <target name="proxy" if="proxy.enabled">
-    <setproxy proxyhost="${proxy.host}" proxyport="${proxy.port}"
-      proxyuser="${proxy.user}" proxypassword="${proxy.pass}"/>
-  </target>
-
-  <target name="mvn.ant.tasks.download" depends="setup.init,mvn.ant.tasks.check,proxy" unless="mvn.ant.tasks.found">
-    <get src="${mvn.ant.task.url}/${mvn.ant.task.jar}" dest="${build.tools.dir}/${mvn.ant.task.jar}" usetimestamp="true"/>
-  </target>
-
-  <target name="mvn.ant.tasks.check">
-    <condition property="mvn.ant.tasks.found">
-      <typefound uri="antlib:org.apache.maven.artifact.ant" name="artifact"/>
-    </condition>
-  </target>
-
-  <target name="mvn.init" depends="mvn.ant.tasks.download" unless="mvn.finished">
-    <!-- Download mvn ant tasks, download dependencies, and setup pom file -->
-    <typedef uri="antlib:org.apache.maven.artifact.ant" classpath="${build.tools.dir}/${mvn.ant.task.jar}"/>
-
-    <!-- remote repositories used to download dependencies from -->
-    <artifact:remoteRepository id="central" url="${mvn.repo}"/>
-    <artifact:remoteRepository id="apache" url="${apache.repo}"/>
-
-    <!-- Pom file information -->
-    <artifact:pom id="pom"
-      groupId="${thrift.groupid}"
-      artifactId="${thrift.artifactid}"
-      version="${version}"
-      url="http://thrift.apache.org"
-      name="Apache Thrift"
-      description="Thrift is a software framework for scalable cross-language services development."
-      packaging="jar"
-    >
-      <remoteRepository refid="central"/>
-      <remoteRepository refid="apache"/>
-      <license name="The Apache Software License, Version 2.0" url="${license}"/>
-      <scm connection="scm:git:https://git-wip-us.apache.org/repos/asf/thrift.git"
-      developerConnection="scm:git:https://git-wip-us.apache.org/repos/asf/thrift.git"
-      url="https://git-wip-us.apache.org/repos/asf?p=thrift.git"
-      />
-      <!-- Thrift Developers -->
-      <developer id="mcslee" name="Mark Slee"/>
-      <developer id="dreiss" name="David Reiss"/>
-      <developer id="aditya" name="Aditya Agarwal"/>
-      <developer id="marck" name="Marc Kwiatkowski"/>
-      <developer id="jwang" name="James Wang"/>
-      <developer id="cpiro" name="Chris Piro"/>
-      <developer id="bmaurer" name="Ben Maurer"/>
-      <developer id="kclark" name="Kevin Clark"/>
-      <developer id="jake" name="Jake Luciani"/>
-      <developer id="bryanduxbury" name="Bryan Duxbury"/>
-      <developer id="esteve" name="Esteve Fernandez"/>
-      <developer id="todd" name="Todd Lipcon"/>
-      <developer id="geechorama" name="Andrew McGeachie"/>
-      <developer id="molinaro" name="Anthony Molinaro"/>
-      <developer id="roger" name="Roger Meier"/>
-      <developer id="jfarrell" name="Jake Farrell"/>
-      <developer id="jensg" name="Jens Geyer"/>
-      <developer id="carl" name="Carl Yeksigian"/>
-
-      <!-- Thrift dependencies list -->
-      <dependency groupId="org.slf4j" artifactId="slf4j-api" version="${slf4j.version}"/>
-      <dependency groupId="javax.servlet" artifactId="servlet-api" version="${servlet.version}" scope="provided"/>
-      <dependency groupId="org.apache.httpcomponents" artifactId="httpclient" version="${httpclient.version}"/>
-      <dependency groupId="org.apache.httpcomponents" artifactId="httpcore" version="${httpcore.version}"/>
-    </artifact:pom>
-
-    <!-- Generate the pom file -->
-    <artifact:writepom pomRefId="pom" file="${pom.xml}"/>
-
-    <!-- Download the dependencies -->
-    <artifact:dependencies filesetId="build-dependency-jars" pomRefId="pom"/>
-
-    <!-- Copy the dependencies to the build/lib dir -->
-    <copy todir="${build.dir}/lib">
-      <fileset refid="build-dependency-jars"/>
-      <mapper type="flatten"/>
-    </copy>
-
-    <!-- Dependencies needed for testing -->
-    <artifact:dependencies filesetId="test-dependency-jars" useScope="runtime">
-      <dependency groupId="org.slf4j" artifactId="slf4j-log4j12" version="${slf4j.version}"/>
-      <dependency groupId="junit" artifactId="junit" version="4.4"/>
-      <dependency groupId="org.mockito" artifactId="mockito-all" version="1.9.5"/>
-    </artifact:dependencies>
-
-    <!-- Copy the test dependencies to the build/lib dir -->
-    <copy todir="${build.dir}/lib">
-      <fileset refid="test-dependency-jars"/>
-      <mapper type="flatten"/>
-    </copy>
-
-    <property name="mvn.finished" value="true"/>
-  </target>
-
-  <macrodef name="signAndDeploy">
-    <!-- Sign and deploy jars to apache repo -->
-    <attribute name="file"/>
-    <attribute name="classifier" default=""/>
-    <attribute name="packaging" default="jar"/>
-    <attribute name="pom" default=""/>
-    <sequential>
-      <artifact:mvn fork="true">
-        <arg value="org.apache.maven.plugins:maven-gpg-plugin:1.6:sign-and-deploy-file"/>
-        <arg value="-DrepositoryId=${maven-repository-id}"/>
-        <arg value="-Durl=${maven-repository-url}"/>
-        <arg value="-DpomFile=@{pom}"/>
-        <arg value="-Dfile=@{file}"/>
-        <arg value="-Dclassifier=@{classifier}"/>
-        <arg value="-Dpackaging=@{packaging}"/>
-        <arg value="-Pgpg"/>
-      </artifact:mvn>
-    </sequential>
-  </macrodef>
-
-  <target name="publish" depends="clean,init,test,dist,javadoc,pack.src">
-    <!-- Compile, package, test and then send release to apache maven repo -->
-    <!-- run with: ant -Drelease=true publish-->
-    <signAndDeploy file="${pom.xml}" packaging="pom" classifier="" pom="${pom.xml}"/>
-    <signAndDeploy file="${jar.file}" classifier="" pom="${pom.xml}"/>
-    <signAndDeploy file="${javadoc.jar.file}" classifier="javadoc" pom="${pom.xml}"/>
-    <signAndDeploy file="${source.jar.file}" classifier="sources" pom="${pom.xml}"/>
-  </target>
-</project>
diff --git a/lib/java/code_quality_tools/findbugs-filter.xml b/lib/java/code_quality_tools/findbugs-filter.xml
new file mode 100644
index 0000000..8a93b0a
--- /dev/null
+++ b/lib/java/code_quality_tools/findbugs-filter.xml
@@ -0,0 +1,51 @@
+<FindBugsFilter>
+    <!--
+        This file controls filtering some of the more obnoxious findbugs reports.
+        Some may be worthy of examination and resolution, others are too nit-picky.
+    -->
+    <Match>
+        <Or>
+            <!-- Filter the missing serialVersionUID errors -->
+            <Bug code="SnVI" />
+            <!-- Filter Malicious code vulnerability Warnings -->
+            <Bug code="EI,EI2" />
+            <!-- Filter Unchecked/unconfirmed cast -->
+            <Bug code="BC" />
+            <!-- Filter Should return a zero length array rather than null? -->
+            <Bug code="PZLA" />
+            <!-- Filter Redundant nullcheck -->
+            <Bug code="RCN" />
+            <!-- Filter Exception is caught when Exception is not thrown -->
+            <Bug code="REC" />
+            <!-- Filter Switch statement found where default case is missing -->
+            <Bug code="SF" />
+            <!-- Filter Unread public/protected field -->
+            <Bug code="UrF" />
+            <!-- Filter Field not initialized in constructor and dereferenced -->
+            <Bug code="UwF" />
+        </Or>
+    </Match>
+     <Match>
+        <!-- Filter method invokes System.exit(...), which shuts down the entire virtual machine -->
+        <Class name="org.apache.thrift.transport.TFileTransport" />
+        <Method name="printUsage" />
+        <Bug code="Dm" />
+     </Match>
+     <Match>
+        <!-- Filter method might ignore java.lang.Exception -->
+       <Class name="org.apache.thrift.transport.TSimpleFileTransport" />
+       <Method name="close" />
+       <Bug code="DE" />
+     </Match>
+     <Match>
+        <!-- Filter method might ignore java.lang.Exception -->
+       <Class name="org.apache.thrift.TNonblockingMultiFetchClient$MultiFetch" />
+       <Method name="run" />
+       <Bug code="DE" />
+     </Match>
+     <Match>
+        <!-- Filter Class defines non-transient non-serializable instance field -->
+       <Class name="org.apache.thrift.server.TServlet" />
+       <Bug code="Se" />
+     </Match>
+</FindBugsFilter>
diff --git a/lib/java/gradle.properties b/lib/java/gradle.properties
new file mode 100644
index 0000000..e99788f
--- /dev/null
+++ b/lib/java/gradle.properties
@@ -0,0 +1,33 @@
+# This file is shared currently between this Gradle build and the
+# Ant builds for fd303 and JavaScript. Keep the dotted notation for
+# the properties to minimize the changes in the dependencies.
+thrift.version=1.0.0
+thrift.groupid=org.apache.thrift
+release=false
+
+# Local Install paths
+install.path=/usr/local/lib
+install.javadoc.path=/usr/local/lib
+
+# Test execution properties
+testPort=9090
+
+# Test with Clover Code coverage (disabled by default)
+cloverEnabled=false
+
+# Maven dependency download locations
+mvn.repo=http://repo1.maven.org/maven2
+apache.repo=https://repository.apache.org/content/repositories/releases
+
+# Apache Maven publish
+license=http://www.apache.org/licenses/LICENSE-2.0.txt
+maven-repository-url=https://repository.apache.org/service/local/staging/deploy/maven2
+maven-repository-id=apache.releases.https
+
+# Dependency versions
+httpclient.version=4.4.1
+httpcore.version=4.4.1
+slf4j.version=1.7.12
+servlet.version=2.5
+junit.version=4.12
+mockito.version=1.9.5
diff --git a/lib/java/gradle/additionalArtifacts.gradle b/lib/java/gradle/additionalArtifacts.gradle
new file mode 100644
index 0000000..201469d
--- /dev/null
+++ b/lib/java/gradle/additionalArtifacts.gradle
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Following Gradle best practices to keep build logic organized
+
+task sourcesJar(type: Jar, group: 'Build') {
+    description = 'Assembles a jar archive containing the main Java sources.'
+
+    classifier 'sources'
+    from sourceSets.main.allSource
+}
+
+task javadocJar(type: Jar, dependsOn: javadoc, group: 'Build') {
+    description = 'Assembles a jar archive containing the JavaDoc.'
+
+    classifier 'javadoc'
+    from javadoc.destinationDir
+}
+
+artifacts {
+    archives sourcesJar
+    archives javadocJar
+}
+
diff --git a/lib/java/gradle/cloverCoverage.gradle b/lib/java/gradle/cloverCoverage.gradle
new file mode 100644
index 0000000..cef0e79
--- /dev/null
+++ b/lib/java/gradle/cloverCoverage.gradle
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Following Gradle best practices to keep build logic organized
+
+// Keep this as an optional feature for now, disabled by default
+if (Boolean.parseBoolean(project.cloverEnabled)) {
+    apply plugin: 'com.bmuschko.clover'
+
+    dependencies {
+        clover 'org.openclover:clover:4.2.+'
+    }
+
+    clover {
+
+        testIncludes = ['**/Test*.java']
+        // Exclude the generated test code from code coverage
+        testExcludes = ['thrift/test/Test*.java']
+
+        compiler {
+            encoding = 'UTF-8'
+            debug = true
+        }
+
+        report {
+            html = true
+            pdf = true
+        }
+    }
+
+    build.dependsOn cloverGenerateReport
+}
diff --git a/lib/java/gradle/codeQualityChecks.gradle b/lib/java/gradle/codeQualityChecks.gradle
new file mode 100644
index 0000000..9572ca1
--- /dev/null
+++ b/lib/java/gradle/codeQualityChecks.gradle
@@ -0,0 +1,40 @@
+
+// =================================================================
+// Configure the Gradle code quality plugins here.
+//
+
+apply plugin: 'findbugs'
+
+findbugs {
+    ignoreFailures = true
+    toolVersion = '3.0.1'
+    sourceSets = [ sourceSets.main ]
+    effort = 'max'
+    reportLevel = 'low'
+    excludeFilter = file('code_quality_tools/findbugs-filter.xml')
+}
+
+tasks.withType(FindBugs) {
+    reports {
+        text.enabled = false
+        html.enabled = true
+        xml.enabled = false
+    }
+}
+
+apply plugin: 'pmd'
+
+pmd {
+    ignoreFailures = true
+    toolVersion = '6.0.0'
+    sourceSets = [ sourceSets.main ]
+    targetJdk = sourceCompatibility
+    ruleSets = [ 'java-basic' ]
+}
+
+tasks.withType(Pmd) {
+    reports {
+        html.enabled = true
+        xml.enabled = false
+    }
+}
diff --git a/lib/java/gradle/environment.gradle b/lib/java/gradle/environment.gradle
new file mode 100644
index 0000000..9b7eb1e
--- /dev/null
+++ b/lib/java/gradle/environment.gradle
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Following Gradle best practices to keep build logic organized
+
+// Override the build directory if CMake is used (allows for out-of-tree-builds)
+if (hasProperty('build.dir')) {
+    buildDir = file(property('build.dir'))
+}
+
+// In order to remain compatible with other Ant based builds in the system
+// we convert the gradle.properties into DSL friendly camelCased properties
+ext.installPath = property('install.path')
+ext.installJavadocPath = property('install.javadoc.path')
+
+ext.thriftRoot = file('../..')
+
+if (hasProperty('thrift.compiler')) {
+    ext.thriftCompiler = property('thrift.compiler')
+} else {
+    ext.thriftCompiler = "$thriftRoot/compiler/cpp/thrift"
+}
+
+ext.mvnRepo = property('mvn.repo')
+ext.apacheRepo = property('apache.repo')
+ext.mavenRepositoryUrl = property('maven-repository-url')
+
+// Versions used in this project
+ext.httpclientVersion = property('httpclient.version')
+ext.httpcoreVersion = property('httpcore.version')
+ext.servletVersion = property('servlet.version')
+ext.slf4jVersion = property('slf4j.version')
+ext.junitVersion = property('junit.version')
+ext.mockitoVersion = property('mockito.version')
+
+// In this section you declare where to find the dependencies of your project
+repositories {
+    maven {
+        name 'Maven Central Repository'
+        url mvnRepo
+    }
+    maven {
+        name 'Apache Maven Repository'
+        url apacheRepo
+    }
+}
+
+dependencies {
+    compile "org.slf4j:slf4j-api:${slf4jVersion}"
+    compile "org.apache.httpcomponents:httpclient:${httpclientVersion}"
+    compile "org.apache.httpcomponents:httpcore:${httpcoreVersion}"
+    compile "javax.servlet:servlet-api:${servletVersion}"
+
+    testCompile "junit:junit:${junitVersion}"
+    testCompile "org.mockito:mockito-all:${mockitoVersion}"
+    testRuntime "org.slf4j:slf4j-log4j12:${slf4jVersion}"
+}
diff --git a/lib/java/gradle/functionalTests.gradle b/lib/java/gradle/functionalTests.gradle
new file mode 100644
index 0000000..c420d12
--- /dev/null
+++ b/lib/java/gradle/functionalTests.gradle
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Following Gradle best practices to keep build logic organized
+
+// ----------------------------------------------------------------------------
+// Functional testing harness creation. This helps run the cross-check tests.
+// The Makefile precross target invokes the shadowJar task and the tests.json
+// code is changed to call runclient or runserver as needed.
+
+// ----------------------------------------------------------------------------
+// Cross Test sources are separated in their own sourceSet
+//
+sourceSets {
+    crossTest {
+        java {
+            srcDir 'test'
+            include '**/test/TestClient.java'
+            include '**/test/TestServer.java'
+            include '**/test/TestNonblockingServer.java'
+        }
+    }
+}
+
+configurations {
+    crossTestCompile { extendsFrom testCompile }
+    crossTestRuntime { extendsFrom crossTestCompile, testRuntime }
+}
+
+dependencies {
+    crossTestCompile sourceSets.main.output
+    crossTestCompile sourceSets.test.output
+}
+
+// I am using shadow plugin to make a self contained functional test Uber JAR that
+// eliminates startup problems with wrapping the cross-check harness in Gradle.
+// This is used by the runner scripts as the single classpath entry which
+// allows the process to be as lightweight as it can.
+shadowJar {
+    description = 'Assemble a test JAR file for cross-check execution'
+    // make sure the runners are created when this runs
+    dependsOn 'generateRunnerScriptForClient', 'generateRunnerScriptForServer', 'generateRunnerScriptForNonblockingServer'
+
+    baseName = 'functionalTest'
+    destinationDir = file("$buildDir/functionalTestJar")
+    classifier = null
+
+    // We do not need a version number for this internal jar
+    version = null
+
+    // Bundle the complete set of unit test classes including generated code
+    // and the runtime dependencies in one JAR to expedite execution.
+    from sourceSets.test.output
+    from sourceSets.crossTest.output
+    configurations = [project.configurations.testRuntime]
+}
+
+// Common script runner configuration elements
+def scriptExt = ''
+def execExt = ''
+def scriptHead = '#!/bin/bash'
+def args = '$*'
+
+// Although this is marked internal it is an available and stable interface
+if (org.gradle.internal.os.OperatingSystem.current().windows) {
+    scriptExt = '.bat'
+    execExt = '.exe'
+    scriptHead = '@echo off'
+    args = '%*'
+}
+
+// The Java executable to use with the runner scripts
+def javaExe = file("${System.getProperty('java.home')}/bin/java${execExt}").canonicalPath
+// The common Uber jar path
+def jarPath = shadowJar.archivePath.canonicalPath
+def trustStore = file('test/.truststore').canonicalPath
+def keyStore = file('test/.keystore').canonicalPath
+
+task generateRunnerScriptForClient(group: 'Build') {
+    description = 'Generate a runner script for cross-check tests with TestClient'
+
+    def clientFile = file("$buildDir/runclient${scriptExt}")
+
+    def runClientText = """\
+${scriptHead}
+
+"${javaExe}" -cp "$jarPath" "-Djavax.net.ssl.trustStore=$trustStore" -Djavax.net.ssl.trustStorePassword=thrift org.apache.thrift.test.TestClient $args
+"""
+    inputs.property 'runClientText', runClientText
+    outputs.file clientFile
+
+    doLast {
+        clientFile.parentFile.mkdirs()
+        clientFile.text = runClientText
+        clientFile.setExecutable(true, false)
+    }
+}
+
+task generateRunnerScriptForServer(group: 'Build') {
+    description = 'Generate a runner script for cross-check tests with TestServer'
+
+    def serverFile = file("$buildDir/runserver${scriptExt}")
+
+    def runServerText = """\
+${scriptHead}
+
+"${javaExe}" -cp "$jarPath" "-Djavax.net.ssl.keyStore=$keyStore" -Djavax.net.ssl.keyStorePassword=thrift org.apache.thrift.test.TestServer $args
+"""
+
+    inputs.property 'runServerText', runServerText
+    outputs.file serverFile
+
+    doLast {
+        serverFile.parentFile.mkdirs()
+        serverFile.text = runServerText
+        serverFile.setExecutable(true, false)
+    }
+}
+
+task generateRunnerScriptForNonblockingServer(group: 'Build') {
+    description = 'Generate a runner script for cross-check tests with TestNonblockingServer'
+
+    def serverFile = file("$buildDir/runnonblockingserver${scriptExt}")
+
+    def runServerText = """\
+${scriptHead}
+
+"${javaExe}" -cp "$jarPath" "-Djavax.net.ssl.keyStore=$keyStore" -Djavax.net.ssl.keyStorePassword=thrift org.apache.thrift.test.TestNonblockingServer $args
+"""
+
+    inputs.property 'runServerText', runServerText
+    outputs.file serverFile
+
+    doLast {
+        serverFile.parentFile.mkdirs()
+        serverFile.text = runServerText
+        serverFile.setExecutable(true, false)
+    }
+}
diff --git a/lib/java/gradle/generateTestThrift.gradle b/lib/java/gradle/generateTestThrift.gradle
new file mode 100644
index 0000000..9673e5b
--- /dev/null
+++ b/lib/java/gradle/generateTestThrift.gradle
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Following Gradle best practices to keep build logic organized
+
+// Generated code locations for Unit tests
+ext.genSrc = file("$buildDir/gen-java")
+ext.genBeanSrc = file("$buildDir/gen-javabean")
+ext.genReuseSrc = file("$buildDir/gen-javareuse")
+ext.genFullCamelSrc = file("$buildDir/gen-fullcamel")
+
+// Add the generated code directories to the test source set
+sourceSets {
+    test.java.srcDirs genSrc, genBeanSrc, genReuseSrc, genFullCamelSrc
+}
+
+// ----------------------------------------------------------------------------
+// Code generation for Unit Testing
+
+// A callable closure to make this easier
+ext.thriftCompile = { Task task, String thriftFileName, String generator = 'java', File outputDir = genSrc ->
+    def thriftFile = file("$thriftRoot/test/$thriftFileName")
+    assert thriftFile.exists()
+
+    task.inputs.file thriftFile
+    task.outputs.dir outputDir
+
+    task.doLast {
+        outputDir.mkdirs()
+        def result = exec {
+            executable file(thriftCompiler)
+            args '--gen', generator
+            args '-out', outputDir
+            args thriftFile
+            standardOutput = task.outputBuffer
+            errorOutput = task.outputBuffer
+            ignoreExitValue = true
+        }
+        if (result.exitValue != 0) {
+            // Only show the Thrift compiler output on failures, cuts down on noise!
+            println task.outputBuffer.toString()
+            result.rethrowFailure()
+        }
+    }
+}
+
+task generate(group: 'Build') {
+    description = 'Generate all unit test Thrift sources'
+    compileTestJava.dependsOn it
+}
+
+task generateJava(group: 'Build') {
+    description = 'Generate the thrift gen-java source'
+    generate.dependsOn it
+
+    ext.outputBuffer = new ByteArrayOutputStream()
+
+    thriftCompile(it, 'ThriftTest.thrift')
+    thriftCompile(it, 'JavaTypes.thrift')
+    thriftCompile(it, 'DebugProtoTest.thrift')
+    thriftCompile(it, 'OptionalRequiredTest.thrift')
+    thriftCompile(it, 'ManyOptionals.thrift')
+    thriftCompile(it, 'JavaDeepCopyTest.thrift')
+    thriftCompile(it, 'EnumContainersTest.thrift')
+}
+
+task generateBeanJava(group: 'Build') {
+    description = 'Generate the thrift gen-javabean source'
+    generate.dependsOn it
+
+    ext.outputBuffer = new ByteArrayOutputStream()
+
+    thriftCompile(it, 'JavaBeansTest.thrift', 'java:beans,nocamel', genBeanSrc)
+}
+
+task generateReuseJava(group: 'Build') {
+    description = 'Generate the thrift gen-javareuse source'
+    generate.dependsOn it
+
+    ext.outputBuffer = new ByteArrayOutputStream()
+
+    thriftCompile(it, 'FullCamelTest.thrift', 'java:fullcamel', genFullCamelSrc)
+}
+
+task generateFullCamelJava(group: 'Build') {
+    description = 'Generate the thrift gen-fullcamel source'
+    generate.dependsOn it
+
+    ext.outputBuffer = new ByteArrayOutputStream()
+
+    thriftCompile(it, 'ReuseObjects.thrift', 'java:reuse-objects', genReuseSrc)
+}
diff --git a/lib/java/gradle/publishing.gradle b/lib/java/gradle/publishing.gradle
new file mode 100644
index 0000000..961d58f
--- /dev/null
+++ b/lib/java/gradle/publishing.gradle
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Following Gradle best practices to keep build logic organized
+
+// ----------------------------------------------------------------------------
+// Installation subtasks, not used currently, we use "make install/fast"
+task installDist(type: Copy, group: 'Install') {
+    description = "Copy Thrift JAR and dependencies into $installPath location"
+
+    destinationDir = file(installPath)
+
+    from jar
+    from configurations.compile
+}
+
+task installJavadoc(type: Copy, group: 'Install', dependsOn: javadoc) {
+    description = "Install Thrift JavaDoc into $installJavadocPath location"
+
+    destinationDir = file(installJavadocPath)
+
+    from javadoc.destinationDir
+}
+
+// This is not needed by Gradle builds but the remaining Ant builds seem to
+// need access to the generated test classes for Thrift unit tests so we
+// assist them to use it this way.
+task copyDependencies(type: Copy, group: 'Build') {
+    description = 'Copy runtime dependencies in a common location for other Ant based projects'
+    project.assemble.dependsOn it
+
+    destinationDir = file("$buildDir/deps")
+    from configurations.testRuntime
+    // exclude some very specific unit test dependencies
+    exclude '**/junit*.jar', '**/mockito*.jar', '**/hamcrest*.jar'
+}
+
+// ----------------------------------------------------------------------------
+// Allow this configuration to be shared between install and uploadArchives tasks
+def configurePom(pom) {
+    pom.project {
+        name 'Apache Thrift'
+        description 'Thrift is a software framework for scalable cross-language services development.'
+        packaging 'jar'
+        url 'http://thrift.apache.org'
+
+        scm {
+            url 'https://git-wip-us.apache.org/repos/asf?p=thrift.git'
+            connection 'scm:git:https://git-wip-us.apache.org/repos/asf/thrift.git'
+            developerConnection 'scm:git:https://git-wip-us.apache.org/repos/asf/thrift.git'
+        }
+
+        licenses {
+            license {
+                name 'The Apache Software License, Version 2.0'
+                url "${project.license}"
+                distribution 'repo'
+            }
+        }
+
+        developers {
+            developer {
+                id 'dev'
+                name 'Apache Thrift Developers'
+                email 'dev@thrift.apache.org'
+            }
+        }
+    }
+
+    pom.whenConfigured {
+        // Fixup the scope for servlet-api to be 'provided' instead of 'compile'
+        dependencies.find { dep -> dep.groupId == 'javax.servlet' && dep.artifactId == 'servlet-api' }.with {
+            // it.optional = true
+            it.scope = 'provided'
+        }
+    }
+}
+
+install {
+    repositories.mavenInstaller {
+        configurePom(pom)
+    }
+}
+
+uploadArchives {
+    dependsOn test // make sure we run unit tests when publishing
+    repositories.mavenDeployer {
+        // signPom will silently do nothing when no signing information is provided
+        beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
+        repository(url: project.mavenRepositoryUrl) {
+            if (project.hasProperty('mavenUser') && project.hasProperty('mavenPassword')) {
+                authentication(userName: mavenUser, password: mavenPassword)
+            }
+        }
+        configurePom(pom)
+    }
+}
+
+// Signing configuration, optional, only when release and uploadArchives is activated
+signing {
+    required { !version.endsWith("SNAPSHOT") && gradle.taskGraph.hasTask("uploadArchives") }
+    sign configurations.archives
+}
diff --git a/lib/java/gradle/sourceConfiguration.gradle b/lib/java/gradle/sourceConfiguration.gradle
new file mode 100644
index 0000000..decc6a2
--- /dev/null
+++ b/lib/java/gradle/sourceConfiguration.gradle
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Following Gradle best practices to keep build logic organized
+
+// ----------------------------------------------------------------------------
+// source sets for main and test sources
+sourceSets {
+    main {
+        java {
+            srcDir 'src'
+        }
+    }
+    test {
+        java {
+            srcDir 'test'
+            // see functionalTests.gradle for these files
+            exclude '**/test/TestClient.java'
+            exclude '**/test/TestServer.java'
+            exclude '**/test/TestNonblockingServer.java'
+        }
+        resources {
+            srcDir 'test'
+            include 'log4j.properties'
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+// Compiler configuration details
+
+sourceCompatibility = '1.6'
+targetCompatibility = '1.6'
+
+tasks.withType(JavaCompile) {
+    options.encoding = 'UTF-8'
+    options.debug = true
+    options.deprecation = true
+    // options.compilerArgs.addAll('-Xlint:unchecked')
+}
+
+// ----------------------------------------------------------------------------
+// Jar packaging details
+processResources {
+    into('META-INF') {
+        from "$thriftRoot/LICENSE"
+        from "$thriftRoot/NOTICE"
+        rename('(.+)', '$1.txt')
+    }
+}
+
+jar {
+    project.test.dependsOn it
+    manifest {
+        attributes([
+            "Implementation-Version": "${project.version}",
+            "Bundle-ManifestVersion": "2",
+            "Bundle-SymbolicName": "${project.group}",
+            "Bundle-Name": "Apache Thrift",
+            "Bundle-Version": "${project.version}",
+            "Bundle-Description": "Apache Thrift library",
+            "Bundle-License": "${project.license}",
+            "Bundle-ActivationPolicy": "lazy",
+            "Export-Package": "${project.group}.async;uses:=\"${project.group}.protocol,${project.group}.transport,org.slf4j,${project.group}\";version=\"${version}\",${project.group}.protocol;uses:=\"${project.group}.transport,${project.group},${project.group}.scheme\";version=\"${version}\",${project.group}.server;uses:=\"${project.group}.transport,${project.group}.protocol,${project.group},org.slf4j,javax.servlet,javax.servlet.http\";version=\"${version}\",${project.group}.transport;uses:=\"${project.group}.protocol,${project.group},org.apache.http.client,org.apache.http.params,org.apache.http.entity,org.apache.http.client.methods,org.apache.http,org.slf4j,javax.net.ssl,javax.net,javax.security.sasl,javax.security.auth.callback\";version=\"${version}\",${project.group};uses:=\"${project.group}.protocol,${project.group}.async,${project.group}.server,${project.group}.transport,org.slf4j,org.apache.log4j,${project.group}.scheme\";version=\"${version}\",${project.group}.meta_data;uses:=\"${project.group}\";version=\"${version}\",${project.group}.scheme;uses:=\"${project.group}.protocol,${project.group}\";version=\"${version}\"",
+            "Import-Package": "javax.net,javax.net.ssl,javax.security.auth.callback,javax.security.sasl,javax.servlet;resolution:=optional,javax.servlet.http;resolution:=optional,org.slf4j;resolution:=optional;version=\"[1.4,2)\",org.apache.http.client;resolution:=optional,org.apache.http.params;resolution:=optional,org.apache.http.entity;resolution:=optional,org.apache.http.client.methods;resolution:=optional,org.apache.http;resolution:=optional"
+        ])
+    }
+}
diff --git a/lib/java/gradle/unitTests.gradle b/lib/java/gradle/unitTests.gradle
new file mode 100644
index 0000000..61f2fbd
--- /dev/null
+++ b/lib/java/gradle/unitTests.gradle
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Following Gradle best practices to keep build logic organized
+
+// Bundle the test classes in a JAR for other Ant based builds
+task testJar(type: Jar, group: 'Build') {
+    description = 'Assembles a jar archive containing the test classes.'
+    project.test.dependsOn it
+
+    classifier 'test'
+    from sourceSets.test.output
+}
+
+// ----------------------------------------------------------------------------
+// Unit test tasks and configurations
+
+// Help the up to date algorithm to make these tests done
+ext.markTaskDone = { task ->
+    def buildFile = file("$buildDir/${task.name}.flag")
+    task.inputs.files task.classpath
+    task.outputs.file buildFile
+    task.doLast {
+        buildFile.text = 'Passed!'
+    }
+}
+
+task deprecatedEqualityTest(type: JavaExec, group: 'Verification') {
+    description = 'Run the non-JUnit test suite '
+    classpath = sourceSets.test.runtimeClasspath
+    main 'org.apache.thrift.test.EqualityTest'
+    markTaskDone(it)
+}
+
+task deprecatedJavaBeansTest(type: JavaExec, group: 'Verification') {
+    description = 'Run the non-JUnit test suite '
+    classpath = sourceSets.test.runtimeClasspath
+    main 'org.apache.thrift.test.JavaBeansTest'
+    markTaskDone(it)
+}
+
+// Main Unit Test task configuration
+test {
+    description="Run the full test suite"
+    dependsOn deprecatedEqualityTest, deprecatedJavaBeansTest
+
+    // Allow repeating tests even after successful execution
+    if (project.hasProperty('rerunTests')) {
+        outputs.upToDateWhen { false }
+    }
+
+    include '**/Test*.class'
+    exclude '**/Test*\$*.class'
+
+    maxHeapSize = '512m'
+    forkEvery = 1
+
+    systemProperties = [
+        'build.test': "${compileTestJava.destinationDir}",
+        'test.port': "${testPort}",
+        'javax.net.ssl.trustStore': "${projectDir}/test/.truststore",
+        'javax.net.ssl.trustStorePassword': 'thrift',
+        'javax.net.ssl.keyStore': "${projectDir}/test/.keystore",
+        'javax.net.ssl.keyStorePassword': 'thrift'
+    ]
+}
diff --git a/lib/java/gradle/wrapper/gradle-wrapper.jar b/lib/java/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..99340b4
--- /dev/null
+++ b/lib/java/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/lib/java/gradle/wrapper/gradle-wrapper.properties b/lib/java/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..2c2bbe5
--- /dev/null
+++ b/lib/java/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-bin.zip
diff --git a/lib/java/gradlew b/lib/java/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/lib/java/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/lib/java/gradlew.bat b/lib/java/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/lib/java/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/lib/java/settings.gradle b/lib/java/settings.gradle
new file mode 100644
index 0000000..c9bd8bc
--- /dev/null
+++ b/lib/java/settings.gradle
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+rootProject.name = 'libthrift'
diff --git a/lib/java/src/org/apache/thrift/server/TExtensibleServlet.java b/lib/java/src/org/apache/thrift/server/TExtensibleServlet.java
index d328dd6..75082c0 100644
--- a/lib/java/src/org/apache/thrift/server/TExtensibleServlet.java
+++ b/lib/java/src/org/apache/thrift/server/TExtensibleServlet.java
@@ -63,7 +63,7 @@
    * Returns the appropriate {@link TProcessor}. This will be called <b>once</b> just
    * after the {@link #init()} method
    * 
-   * @return
+   * @return the appropriate {@link TProcessor}
    */
   protected abstract TProcessor getProcessor();
 
@@ -71,7 +71,7 @@
    * Returns the appropriate in {@link TProtocolFactory}. This will be called
    * <b>once</b> just after the {@link #init()} method
    * 
-   * @return
+   * @return the appropriate in {@link TProtocolFactory}
    */
   protected abstract TProtocolFactory getInProtocolFactory();
 
@@ -79,7 +79,7 @@
    * Returns the appropriate out {@link TProtocolFactory}. This will be called
    * <b>once</b> just after the {@link #init()} method
    * 
-   * @return
+   * @return the appropriate out {@link TProtocolFactory}
    */
   protected abstract TProtocolFactory getOutProtocolFactory();
 
diff --git a/lib/java/test/org/apache/thrift/transport/TestTSimpleFileTransport.java b/lib/java/test/org/apache/thrift/transport/TestTSimpleFileTransport.java
index 5d2fb45..7b880f4 100644
--- a/lib/java/test/org/apache/thrift/transport/TestTSimpleFileTransport.java
+++ b/lib/java/test/org/apache/thrift/transport/TestTSimpleFileTransport.java
@@ -27,21 +27,21 @@
   public void testFresh() throws Exception {
     //Test write side
     Path tempFilePathName = Files.createTempFile("TSimpleFileTransportTest", null);
-    Files.delete(tempFilePathName);        
+    Files.delete(tempFilePathName);
     byte[] input_buf = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
     TSimpleFileTransport trans_write = new TSimpleFileTransport(tempFilePathName.toString(),false, true, false);
     assert (!trans_write.isOpen());
     trans_write.open();
     assert(trans_write.isOpen());
     trans_write.write(input_buf);
-    trans_write.write(input_buf,2,2);    
+    trans_write.write(input_buf,2,2);
     trans_write.flush();
     trans_write.close();
-    
+
     //Test read side
     TSimpleFileTransport trans = new TSimpleFileTransport(tempFilePathName.toString(),true, false);
-    assert(trans_write.isOpen());
-    
+    assert(trans.isOpen());
+
     //Simple file trans provides no buffer access
     assert(0 == trans.getBufferPosition());
     assert(null == trans.getBuffer());
@@ -56,19 +56,19 @@
     trans.readAll(buf1, 0, BUFSIZ);
     assert(BUFSIZ == trans.getFilePointer());
     assert(Arrays.equals(new byte[]{1, 2, 3, 4}, buf1));
-    
+
     int bytesRead = trans.read(buf1, 0, BUFSIZ);
     assert(bytesRead > 0);
     for (int i = 0; i < bytesRead; ++i) {
-      assert(buf1[i] == i+5);    
+      assert(buf1[i] == i+5);
     }
-    
+
     trans.seek(0);
     assert(0 == trans.getFilePointer());
     trans.readAll(buf1, 0, BUFSIZ);
     assert(Arrays.equals(new byte[]{1, 2, 3, 4}, buf1));
     assert(BUFSIZ == trans.getFilePointer());
     trans.close();
-    Files.delete(tempFilePathName);      
+    Files.delete(tempFilePathName);
   }
 }
diff --git a/lib/js/test/build.properties b/lib/js/test/build.properties
new file mode 100644
index 0000000..8463668
--- /dev/null
+++ b/lib/js/test/build.properties
@@ -0,0 +1,5 @@
+# Maven Ant tasks Jar details
+mvn.ant.task.version=2.1.3
+mvn.repo=http://repo1.maven.org/maven2
+mvn.ant.task.url=${mvn.repo}/org/apache/maven/maven-ant-tasks/${mvn.ant.task.version}
+mvn.ant.task.jar=maven-ant-tasks-${mvn.ant.task.version}.jar
diff --git a/lib/js/test/build.xml b/lib/js/test/build.xml
index d10a2d1..109c62f 100755
--- a/lib/js/test/build.xml
+++ b/lib/js/test/build.xml
@@ -31,17 +31,21 @@
   <!-- the root directory, where you unpack thrift distibution (e.g. thrift-0.x.x.tar.gz) -->
   <property name="thrift.dir" location="../../../" />
   <property name="thrift.java.dir" location="${thrift.dir}/lib/java" />
+  <property name="build.tools.dir" location="${thrift.java.dir}/build/tools/"/>
+  <property file="${basedir}/build.properties"/>
 
   <!-- Include the base java properties file -->
-  <property file="${thrift.java.dir}/build.properties" />
+  <property file="${thrift.java.dir}/gradle.properties" />
 
   <property name="thrift.compiler" location="${thrift.dir}/compiler/cpp/thrift" />
 
   <path id="libs.classpath">
-    <fileset dir="${thrift.java.dir}/build/">
-      <include name="*.jar" />
+    <fileset dir="${thrift.java.dir}/build/libs">
+      <include name="libthrift*.jar" />
+      <exclude name="libthrift*javadoc.jar" />
+      <exclude name="libthrift*sources.jar" />
     </fileset>
-    <fileset dir="${thrift.java.dir}/build/lib">
+    <fileset dir="${thrift.java.dir}/build/deps">
       <include name="*.jar" />
     </fileset>
     <fileset dir="${build}/lib">
@@ -59,9 +63,10 @@
       <condition>
         <not>
           <resourcecount count="2">
-            <fileset id="fs" dir="${thrift.java.dir}/build">
+            <fileset id="fs" dir="${thrift.java.dir}/build/libs">
               <include name="libthrift*.jar" />
               <exclude name="libthrift*javadoc.jar" />
+              <exclude name="libthrift*sources.jar" />
             </fileset>
           </resourcecount>
         </not>
@@ -84,6 +89,7 @@
 
   <target name="init" depends="dependencies">
     <tstamp />
+    <mkdir dir="${build.tools.dir}"/>
     <mkdir dir="${build}"/>
     <mkdir dir="${build}/js/lib"/>
     <mkdir dir="${build}/lib"/>
@@ -208,7 +214,17 @@
     <delete dir="${genjs}" />
   </target>
 
-  <target name="resolve" unless="mvn.finished">
+  <target name="mvn.ant.tasks.download" depends="init,mvn.ant.tasks.check" unless="mvn.ant.tasks.found">
+    <get src="${mvn.ant.task.url}/${mvn.ant.task.jar}" dest="${build.tools.dir}/${mvn.ant.task.jar}" usetimestamp="true"/>
+  </target>
+
+  <target name="mvn.ant.tasks.check">
+    <condition property="mvn.ant.tasks.found">
+      <typefound uri="antlib:org.apache.maven.artifact.ant" name="artifact"/>
+    </condition>
+  </target>
+
+  <target name="resolve" depends="mvn.ant.tasks.download" unless="mvn.finished">
     <typedef uri="antlib:org.apache.maven.artifact.ant" classpath="${thrift.java.dir}/build/tools/${mvn.ant.task.jar}"/>
 
     <artifact:dependencies filesetId="js.test.dependency.jars">