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/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