<!--
  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 basedir="." default="jar" name="apache-cassandra"
         xmlns:artifact="antlib:org.apache.maven.artifact.ant"
         xmlns:if="ant:if"
         xmlns:unless="ant:unless">

    <fail message="You need to use Ant of version at least 1.10 to continue.">
      <condition>
        <not>
          <antversion atleast="1.10"/>
        </not>
      </condition>
    </fail>

    <property environment="env"/>
    <property file="build.properties" />
    <property file="build.properties.default" />
    <property name="debuglevel" value="source,lines,vars"/>

    <!-- default version and SCM information -->
    <property name="base.version" value="4.0.5"/>
    <property name="scm.connection" value="scm:https://gitbox.apache.org/repos/asf/cassandra.git"/>
    <property name="scm.developerConnection" value="scm:https://gitbox.apache.org/repos/asf/cassandra.git"/>
    <property name="scm.url" value="https://gitbox.apache.org/repos/asf?p=cassandra.git;a=tree"/>

    <!-- directory details -->
    <property name="basedir" value="."/>
    <property name="build.src" value="${basedir}/src"/>
    <property name="build.src.java" value="${basedir}/src/java"/>
    <property name="build.src.antlr" value="${basedir}/src/antlr"/>
    <property name="build.src.resources" value="${basedir}/src/resources"/>
    <property name="build.src.gen-java" value="${basedir}/src/gen-java"/>
    <property name="build.lib" value="${basedir}/lib"/>
    <property name="build.dir" value="${basedir}/build"/>
    <property name="build.dir.lib" value="${basedir}/build/lib"/>
    <property name="build.test.dir" value="${build.dir}/test"/>
    <property name="build.classes" value="${build.dir}/classes"/>
    <property name="build.classes.main" value="${build.classes}/main" />
    <property name="javadoc.dir" value="${build.dir}/javadoc"/>
    <property name="interface.dir" value="${basedir}/interface"/>
    <property name="test.dir" value="${basedir}/test"/>
    <property name="test.resources" value="${test.dir}/resources"/>
    <property name="test.lib" value="${build.dir}/test/lib"/>
    <property name="test.classes" value="${build.dir}/test/classes"/>
    <property name="test.conf" value="${test.dir}/conf"/>
    <property name="test.data" value="${test.dir}/data"/>
    <property name="test.name" value="*Test"/>
    <property name="test.classlistfile" value="testlist.txt"/>
    <property name="test.classlistprefix" value="unit"/>
    <property name="benchmark.name" value=""/>
    <property name="test.methods" value=""/>
    <property name="test.unit.src" value="${test.dir}/unit"/>
    <property name="test.long.src" value="${test.dir}/long"/>
    <property name="test.burn.src" value="${test.dir}/burn"/>
    <property name="test.memory.src" value="${test.dir}/memory"/>
    <property name="test.microbench.src" value="${test.dir}/microbench"/>
    <property name="test.distributed.src" value="${test.dir}/distributed"/>
    <property name="test.compression.algo" value="LZ4"/>
    <property name="test.driver.connection_timeout_ms" value="5000"/>
    <property name="test.driver.read_timeout_ms" value="12000"/>
    <property name="dist.dir" value="${build.dir}/dist"/>
    <property name="tmp.dir" value="${java.io.tmpdir}"/>

    <property name="doc.dir" value="${basedir}/doc"/>

    <condition property="version" value="${base.version}">
      <isset property="release"/>
    </condition>
    <property name="version" value="${base.version}-SNAPSHOT"/>
    <property name="version.properties.dir"
              value="${build.src.resources}/org/apache/cassandra/config/" />
    <property name="final.name" value="${ant.project.name}-${version}"/>

    <property name="local.repository" value="${user.home}/.m2/repository" />

    <!-- details of what version of Maven ANT Tasks to fetch -->
    <property name="maven-ant-tasks.version" value="2.1.3" />
    <property name="maven-ant-tasks.local" value="${local.repository}/org/apache/maven/maven-ant-tasks"/>
    <property name="maven-ant-tasks.url"
              value="https://repo.maven.apache.org/maven2/org/apache/maven/maven-ant-tasks" />
    <!-- details of how and which Maven repository we publish to -->
    <property name="maven.version" value="3.0.3" />
    <condition property="maven-repository-url" value="https://repository.apache.org/service/local/staging/deploy/maven2">
      <isset property="release"/>
    </condition>
    <condition property="maven-repository-id" value="apache.releases.https">
      <isset property="release"/>
    </condition>
    <property name="maven-repository-url" value="https://repository.apache.org/content/repositories/snapshots"/>
    <property name="maven-repository-id" value="apache.snapshots.https"/>

    <property name="test.timeout" value="240000" />
    <property name="test.memory.timeout" value="480000" />
    <property name="test.long.timeout" value="600000" />
    <property name="test.burn.timeout" value="60000000" />
    <property name="test.distributed.timeout" value="900000" />

    <!-- default for cql tests. Can be override by -Dcassandra.test.use_prepared=false -->
    <property name="cassandra.test.use_prepared" value="true" />

    <!-- skip flushing schema tables during tests -->
    <property name="cassandra.test.flush_local_schema_changes" value="false" />

    <!-- https://www.eclemma.org/jacoco/ -->
    <property name="jacoco.export.dir" value="${build.dir}/jacoco/" />
    <property name="jacoco.partials.dir" value="${jacoco.export.dir}/partials" />
    <property name="jacoco.partialexecfile" value="${jacoco.partials.dir}/partial.exec" />
    <property name="jacoco.finalexecfile" value="${jacoco.export.dir}/jacoco.exec" />
    <property name="jacoco.version" value="0.8.6"/>

    <property name="byteman.version" value="4.0.6"/>
    <property name="jamm.version" value="0.3.2"/>
    <property name="ecj.version" value="4.6.1"/>
    <property name="ohc.version" value="0.5.1"/>
    <property name="asm.version" value="7.1"/>
    <property name="allocation-instrumenter.version" value="3.1.0"/>
    <property name="bytebuddy.version" value="1.10.10"/>
    <property name="jflex.version" value="1.8.2"/>

    <!-- https://mvnrepository.com/artifact/net.openhft/chronicle-bom/1.16.23 -->
    <property name="chronicle-queue.version" value="5.20.123" />
    <property name="chronicle-core.version" value="2.20.126" />
    <property name="chronicle-bytes.version" value="2.20.111" />
    <property name="chronicle-wire.version" value="2.20.117" />
    <property name="chronicle-threads.version" value="2.20.111" />

    <condition property="maven-ant-tasks.jar.exists">
      <available file="${build.dir}/maven-ant-tasks-${maven-ant-tasks.version}.jar" />
    </condition>

    <condition property="maven-ant-tasks.jar.local">
      <available file="${maven-ant-tasks.local}/${maven-ant-tasks.version}/maven-ant-tasks-${maven-ant-tasks.version}.jar" />
    </condition>

    <condition property="is.source.artifact">
      <available file="${build.src.java}" type="dir" />
    </condition>

    <!-- Check if all tests are being run or just one. If it's all tests don't spam the console with test output.
         If it's an individual test print the output from the test under the assumption someone is debugging the test
         and wants to know what is going on without having to context switch to the log file that is generated.
         Debug level output still needs to be retrieved from the log file.  -->
    <script language="javascript">
        if (project.getProperty("cassandra.keepBriefBrief") == null)
        {
            if (project.getProperty("test.name").equals("*Test"))
                project.setProperty("cassandra.keepBriefBrief", "true");
            else
                project.setProperty("cassandra.keepBriefBrief", "false");
        }
    </script>

    <condition property="java.version.8">
        <equals arg1="${ant.java.version}" arg2="1.8"/>
    </condition>
    <condition property="java.version.11">
        <not><isset property="java.version.8"/></not>
    </condition>
    <fail><condition><not><or>
        <isset property="java.version.8"/>
        <isset property="java.version.11"/>
    </or></not></condition></fail>

    <resources id="_jvm11_arg_items">
        <string>-Djdk.attach.allowAttachSelf=true</string>

        <string>-XX:+UseConcMarkSweepGC</string>
        <string>-XX:+CMSParallelRemarkEnabled</string>
        <string>-XX:SurvivorRatio=8</string>
        <string>-XX:MaxTenuringThreshold=1</string>
        <string>-XX:CMSInitiatingOccupancyFraction=75</string>
        <string>-XX:+UseCMSInitiatingOccupancyOnly</string>
        <string>-XX:CMSWaitDuration=10000</string>
        <string>-XX:+CMSParallelInitialMarkEnabled</string>
        <string>-XX:+CMSEdenChunksRecordAlways</string>

        <string>--add-exports java.base/jdk.internal.misc=ALL-UNNAMED</string>
        <string>--add-exports java.base/jdk.internal.ref=ALL-UNNAMED</string>
        <string>--add-exports java.base/sun.nio.ch=ALL-UNNAMED</string>
        <string>--add-exports java.management.rmi/com.sun.jmx.remote.internal.rmi=ALL-UNNAMED</string>
        <string>--add-exports java.rmi/sun.rmi.registry=ALL-UNNAMED</string>
        <string>--add-exports java.rmi/sun.rmi.server=ALL-UNNAMED</string>
        <string>--add-exports java.sql/java.sql=ALL-UNNAMED</string>

        <string>--add-opens java.base/java.lang.module=ALL-UNNAMED</string>
        <string>--add-opens java.base/java.net=ALL-UNNAMED</string>
        <string>--add-opens java.base/jdk.internal.loader=ALL-UNNAMED</string>
        <string>--add-opens java.base/jdk.internal.ref=ALL-UNNAMED</string>
        <string>--add-opens java.base/jdk.internal.reflect=ALL-UNNAMED</string>
        <string>--add-opens java.base/jdk.internal.math=ALL-UNNAMED</string>
        <string>--add-opens java.base/jdk.internal.module=ALL-UNNAMED</string>
        <string>--add-opens java.base/jdk.internal.util.jar=ALL-UNNAMED</string>
        <string>--add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED</string>
    </resources>
    <pathconvert property="_jvm_args_concat" refid="_jvm11_arg_items" pathsep=" "/>
    <condition property="java11-jvmargs" value="${_jvm_args_concat}" else="">
        <not>
            <equals arg1="${ant.java.version}" arg2="1.8"/>
        </not>
    </condition>

    <!--
      JVM arguments for tests.

      There is a race condition bug in java 11 (see CASSANDRA-15981) which causes a crash of the
      JVM; this race is between CMS and class unloading.  In java 8 we can cap the metaspace to
      make tests stable on low resource environments, but in java 11 we need to make it unlimited
      (don't define MaxMetaspaceSize) and disable class unloading in CMS outside of a
      stop-the-world pause.

      In java 11 we also need to set a system property to enable netty to use Unsafe direct byte
      buffer construction (see CASSANDRA-16493)
    -->
    <resources id="_jvm8_test_arg_items">
      <!-- TODO see CASSANDRA-16212 - we seem to OOM non stop now after CASSANDRA-16212, so to have clean CI while this gets looked into, disabling limiting metaspace
        <string>-XX:MaxMetaspaceExpansion=64M</string>
        <string>-XX:MaxMetaspaceSize=512M</string>
        <string>-XX:MetaspaceSize=128M</string>
      -->
    </resources>
    <pathconvert property="_jvm8_test_arg_items_concat" refid="_jvm8_test_arg_items" pathsep=" "/>
    <resources id="_jvm11_test_arg_items">
        <string>-XX:-CMSClassUnloadingEnabled</string>
        <string>-Dio.netty.tryReflectionSetAccessible=true</string>
    </resources>
    <pathconvert property="_jvm11_test_arg_items_concat" refid="_jvm11_test_arg_items" pathsep=" "/>
    <condition property="test-jvmargs" value="${_jvm11_test_arg_items_concat}" else="${_jvm8_test_arg_items_concat}">
        <not>
            <equals arg1="${ant.java.version}" arg2="1.8"/>
        </not>
    </condition>

    <!-- needed to compile org.apache.cassandra.utils.JMXServerUtils -->
    <condition property="jdk11-javac-exports" value="--add-exports java.rmi/sun.rmi.registry=ALL-UNNAMED" else="">
        <not>
            <equals arg1="${ant.java.version}" arg2="1.8"/>
        </not>
    </condition>
    <condition property="jdk11-javadoc-exports" value="${jdk11-javac-exports} --frames" else="">
        <not>
            <equals arg1="${ant.java.version}" arg2="1.8"/>
        </not>
    </condition>

    <condition property="build.java.11">
        <istrue value="${use.jdk11}"/>
    </condition>

    <condition property="source.version" value="8" else="11">
        <equals arg1="${java.version.8}" arg2="true"/>
    </condition>
    <condition property="target.version" value="8" else="11">
        <equals arg1="${java.version.8}" arg2="true"/>
    </condition>

    <!--
         Add all the dependencies.
    -->
    <path id="maven-ant-tasks.classpath" path="${build.dir}/maven-ant-tasks-${maven-ant-tasks.version}.jar" />
    <path id="cassandra.classpath">
        <pathelement location="${build.classes.main}" />
        <fileset dir="${build.dir.lib}">
            <include name="**/*.jar" />
        </fileset>
    </path>
    <path id="cassandra.classpath.test">
        <file file="${build.dir}/${final.name}.jar"/> <!-- we need the jar for tests and benchmarks (multi-version jar) -->
        <fileset dir="${build.dir.lib}">
            <include name="**/*.jar" />
        </fileset>
        <fileset dir="${test.lib}/jars">
            <include name="**/*.jar" />
            <exclude name="**/ant-*.jar"/>
        </fileset>
    </path>

  <macrodef name="create-javadoc">
    <attribute name="destdir"/>
    <element name="filesets"/>
    <sequential>
      <javadoc destdir="@{destdir}" author="true" version="true" use="true"
        windowtitle="${ant.project.name} API" classpathref="cassandra.classpath"
        bottom="Copyright &amp;copy; 2009-2022 The Apache Software Foundation"
        useexternalfile="yes" encoding="UTF-8" failonerror="false"
        maxmemory="256m" additionalparam="${jdk11-javadoc-exports}">
        <filesets/>
      </javadoc>
      <fail message="javadoc failed">
        <condition>
            <not>
                <available file="@{destdir}/index-all.html" />
            </not>
        </condition>
      </fail>
    </sequential>
  </macrodef>

    <target name="validate-build-conf">
        <condition property="use-jdk11">
            <or>
                <isset property="build.java.11"/>
                <istrue value="${env.CASSANDRA_USE_JDK11}"/>
            </or>
        </condition>
        <fail message="Inconsistent JDK11 options set">
            <condition>
                    <and>
                        <istrue value="${env.CASSANDRA_USE_JDK11}"/>
                        <isset property="use.jdk11"/>
                        <not>
                            <istrue value="${use.jdk11}"/>
                        </not>
                    </and>
            </condition>
                </fail>
        <fail message="Inconsistent JDK11 options set">
            <condition>
                    <and>
                        <isset property="env.CASSANDRA_USE_JDK11"/>
                        <not>
                            <istrue value="${env.CASSANDRA_USE_JDK11}"/>
                        </not>
                        <istrue value="${use.jdk11}"/>
                    </and>
            </condition>
        </fail>
        <fail message="-Duse.jdk11=true or $CASSANDRA_USE_JDK11=true cannot be set when building from java 8">
            <condition>
                <not><or>
                    <not><isset property="java.version.8"/></not>
                    <not><isset property="use-jdk11"/></not>
                </or></not>
            </condition>
        </fail>
        <fail message="-Duse.jdk11=true or $CASSANDRA_USE_JDK11=true must be set when building from java 11">
            <condition>
                <not><or>
                    <isset property="java.version.8"/>
                    <isset property="use-jdk11"/>
                </or></not>
            </condition>
        </fail>
    </target>

    <!--
        Setup the output directories.
    -->
    <target name="init" depends="validate-build-conf">
        <fail unless="is.source.artifact"
            message="Not a source artifact, stopping here." />
        <mkdir dir="${build.classes.main}"/>
        <mkdir dir="${test.lib}"/>
        <mkdir dir="${test.classes}"/>
        <mkdir dir="${stress.test.classes}"/>
        <mkdir dir="${fqltool.test.classes}"/>
        <mkdir dir="${build.src.gen-java}"/>
        <mkdir dir="${build.dir.lib}"/>
        <mkdir dir="${jacoco.export.dir}"/>
        <mkdir dir="${jacoco.partials.dir}"/>
    </target>

    <target name="clean" description="Remove all locally created artifacts">
        <delete dir="${build.test.dir}" />
        <delete dir="${build.classes}" />
        <delete dir="${build.src.gen-java}" />
        <delete dir="${version.properties.dir}" />
        <delete dir="${jacoco.export.dir}" />
        <delete dir="${jacoco.partials.dir}"/>
    </target>
    <target depends="clean" name="cleanall"/>

    <target name="realclean" depends="clean" description="Remove the entire build directory and all downloaded artifacts">
        <delete>
          <fileset dir="${build.lib}" excludes="cassandra-driver-internal-only-*"/>
        </delete>
        <delete dir="${build.dir}" />
        <delete dir="${doc.dir}/build" />
        <delete dir="${doc.dir}/source/tools/nodetool" />
    </target>

    <!--
       This generates the CQL grammar files from Cql.g
    -->
    <target name="check-gen-cql3-grammar">
        <uptodate property="cql3current"
                targetfile="${build.src.gen-java}/org/apache/cassandra/cql3/Cql.tokens">
            <srcfiles dir="${build.src.antlr}">
                <include name="*.g"/>
            </srcfiles>
        </uptodate>
    </target>

    <target name="gen-cql3-grammar" depends="check-gen-cql3-grammar" unless="cql3current">
      <echo>Building Grammar ${build.src.antlr}/Cql.g  ...</echo>
      <java classname="org.antlr.Tool"
            classpathref="cql3-grammar.classpath"
            failonerror="true">
         <arg value="-Xconversiontimeout" />
         <arg value="10000" />
         <arg value="${build.src.antlr}/Cql.g" />
         <arg value="-fo" />
         <arg value="${build.src.gen-java}/org/apache/cassandra/cql3/" />
         <arg value="-Xmaxinlinedfastates"/>
         <arg value="10"/> <!-- default is 60 -->
      </java>
    </target>

    <target name="generate-cql-html" depends="resolver-init" description="Generate HTML from textile source">
        <taskdef classpathref="wikitext.classpath" resource="wikitexttasks.properties" />
        <wikitext-to-html markupLanguage="Textile">
            <fileset dir="${basedir}">
                <include name="doc/cql3/*.textile"/>
            </fileset>
        </wikitext-to-html>
    </target>

    <target name="gen-asciidoc" description="Generate dynamic asciidoc pages" depends="jar" unless="ant.gen-doc.skip">
        <exec executable="make" osfamily="unix" dir="${doc.dir}">
            <arg value="gen-asciidoc"/>
        </exec>
    </target>

    <target name="gen-doc" description="Generate documentation" depends="gen-asciidoc,generate-cql-html" unless="ant.gen-doc.skip">
        <exec executable="make" osfamily="unix" dir="${doc.dir}">
            <arg value="html"/>
        </exec>
    </target>

    <!--
        Generates Java sources for tokenization support from jflex
        grammar files
    -->
    <target name="generate-jflex-java" description="Generate Java from jflex grammar">
        <taskdef classname="jflex.anttask.JFlexTask" classpathref="jflex.classpath" name="jflex" />
        <jflex file="${build.src.java}/org/apache/cassandra/index/sasi/analyzer/StandardTokenizerImpl.jflex" destdir="${build.src.gen-java}/" />
    </target>

    <!--
       Fetch Maven Ant Tasks and Cassandra's dependencies
       These targets are intentionally free of dependencies so that they
       can be run stand-alone from a binary release artifact.
    -->
    <target name="maven-ant-tasks-localrepo" unless="maven-ant-tasks.jar.exists" if="maven-ant-tasks.jar.local"
            depends="init" description="Fetch Maven ANT Tasks from Maven Local Repository">
      <copy file="${maven-ant-tasks.local}/${maven-ant-tasks.version}/maven-ant-tasks-${maven-ant-tasks.version}.jar"
           tofile="${build.dir}/maven-ant-tasks-${maven-ant-tasks.version}.jar"/>
      <property name="maven-ant-tasks.jar.exists" value="true"/>
    </target>

    <target name="maven-ant-tasks-download" depends="init,maven-ant-tasks-localrepo" unless="maven-ant-tasks.jar.exists"
            description="Fetch Maven ANT Tasks from Maven Central Repositroy">
      <echo>Downloading Maven ANT Tasks...</echo>
      <get src="${maven-ant-tasks.url}/${maven-ant-tasks.version}/maven-ant-tasks-${maven-ant-tasks.version}.jar"
           dest="${build.dir}/maven-ant-tasks-${maven-ant-tasks.version}.jar" usetimestamp="true" />
      <copy file="${build.dir}/maven-ant-tasks-${maven-ant-tasks.version}.jar"
            tofile="${maven-ant-tasks.local}/${maven-ant-tasks.version}/maven-ant-tasks-${maven-ant-tasks.version}.jar"/>
    </target>

    <target name="maven-ant-tasks-init" depends="maven-ant-tasks-download,resolver-init" unless="maven-ant-tasks.initialized"
            description="Initialize Maven ANT Tasks">
      <typedef uri="antlib:org.apache.maven.artifact.ant" classpathref="maven-ant-tasks.classpath" />
      <property name="maven-ant-tasks.initialized" value="true"/>
    </target>

    <!-- this task defines the dependencies that will be fetched by Maven ANT Tasks
         the dependencies are re-used for publishing artifacts to Maven Central
         in order to keep everything consistent -->
    <target name="maven-declare-dependencies" depends="maven-ant-tasks-init"
            description="Define dependencies and dependency versions">
      <!-- The parent pom defines the versions of all dependencies -->
      <artifact:pom id="parent-pom"
                    groupId="org.apache.cassandra"
                    artifactId="cassandra-parent"
                    packaging="pom"
                    version="${version}"
                    url="https://cassandra.apache.org"
                    name="Apache Cassandra"
                    inceptionYear="2009"
                    description="The Apache Cassandra Project develops a highly scalable second-generation distributed database, bringing together Dynamo's fully distributed design and Bigtable's ColumnFamily-based data model.">

        <!-- Inherit from the ASF template pom file, ref http://maven.apache.org/pom/asf/ -->
        <parent groupId="org.apache" artifactId="apache" version="22"/>
        <license name="The Apache Software License, Version 2.0" url="https://www.apache.org/licenses/LICENSE-2.0.txt"/>
        <scm connection="${scm.connection}" developerConnection="${scm.developerConnection}" url="${scm.url}"/>
        <dependencyManagement>
          <dependency groupId="org.xerial.snappy" artifactId="snappy-java" version="1.1.2.6"/>
          <dependency groupId="org.lz4" artifactId="lz4-java" version="1.8.0"/>
          <dependency groupId="com.ning" artifactId="compress-lzf" version="0.8.4" scope="provided"/>
          <dependency groupId="com.github.luben" artifactId="zstd-jni" version="1.5.0-4"/>
          <dependency groupId="com.google.guava" artifactId="guava" version="27.0-jre">
            <exclusion groupId="com.google.code.findbugs" artifactId="jsr305" />
            <exclusion groupId="org.codehaus.mojo" artifactId="animal-sniffer-annotations" />
            <exclusion groupId="com.google.guava" artifactId="listenablefuture" />
            <exclusion groupId="com.google.guava" artifactId="failureaccess" />
            <exclusion groupId="org.checkerframework" artifactId="checker-qual" />
            <exclusion groupId="com.google.errorprone" artifactId="error_prone_annotations" />
          </dependency>
          <dependency groupId="org.hdrhistogram" artifactId="HdrHistogram" version="2.1.9"/>
          <dependency groupId="commons-cli" artifactId="commons-cli" version="1.1"/>
          <dependency groupId="commons-codec" artifactId="commons-codec" version="1.9"/>
          <dependency groupId="commons-io" artifactId="commons-io" version="2.6" scope="test"/>
          <dependency groupId="org.apache.commons" artifactId="commons-lang3" version="3.11"/>
          <dependency groupId="org.apache.commons" artifactId="commons-math3" version="3.2"/>
          <dependency groupId="org.antlr" artifactId="antlr" version="3.5.2" scope="provided">
            <exclusion groupId="org.antlr" artifactId="stringtemplate"/>
          </dependency>
          <dependency groupId="org.antlr" artifactId="ST4" version="4.0.8"/>
          <dependency groupId="org.antlr" artifactId="antlr-runtime" version="3.5.2">
            <exclusion groupId="org.antlr" artifactId="stringtemplate"/>
          </dependency>
          <dependency groupId="org.slf4j" artifactId="slf4j-api" version="1.7.25"/>
          <dependency groupId="org.slf4j" artifactId="log4j-over-slf4j" version="1.7.25"/>
          <dependency groupId="org.slf4j" artifactId="jcl-over-slf4j" version="1.7.25" />
          <dependency groupId="ch.qos.logback" artifactId="logback-core" version="1.2.9"/>
          <dependency groupId="ch.qos.logback" artifactId="logback-classic" version="1.2.9"/>
          <dependency groupId="com.fasterxml.jackson.core" artifactId="jackson-core" version="2.13.2"/>
          <dependency groupId="com.fasterxml.jackson.core" artifactId="jackson-databind" version="2.13.2.2"/>
          <dependency groupId="com.fasterxml.jackson.core" artifactId="jackson-annotations" version="2.13.2"/>
          <dependency groupId="com.googlecode.json-simple" artifactId="json-simple" version="1.1"/>
          <dependency groupId="com.boundary" artifactId="high-scale-lib" version="1.0.6"/>
          <dependency groupId="com.github.jbellis" artifactId="jamm" version="${jamm.version}"/>
          <dependency groupId="org.yaml" artifactId="snakeyaml" version="1.26"/>
          <dependency groupId="junit" artifactId="junit" version="4.12" scope="test">
            <exclusion groupId="org.hamcrest" artifactId="hamcrest-core"/>
          </dependency>
          <dependency groupId="org.mockito" artifactId="mockito-core" version="3.2.4" scope="test"/>
          <dependency groupId="org.quicktheories" artifactId="quicktheories" version="0.26" scope="test"/>
          <dependency groupId="com.google.code.java-allocation-instrumenter" artifactId="java-allocation-instrumenter" version="${allocation-instrumenter.version}" scope="test">
            <exclusion groupId="com.google.guava" artifactId="guava"/>
          </dependency>
          <dependency groupId="org.apache.cassandra" artifactId="dtest-api" version="0.0.13" scope="test"/>
          <dependency groupId="org.reflections" artifactId="reflections" version="0.10.2" scope="test"/>
          <dependency groupId="org.apache.hadoop" artifactId="hadoop-core" version="1.0.3" scope="provided">
            <exclusion groupId="org.mortbay.jetty" artifactId="servlet-api"/>
            <exclusion groupId="commons-logging" artifactId="commons-logging"/>
            <exclusion groupId="org.eclipse.jdt" artifactId="core"/>
            <exclusion groupId="ant" artifactId="ant"/>
            <exclusion groupId="junit" artifactId="junit"/>
            <exclusion groupId="org.codehaus.jackson" artifactId="jackson-mapper-asl"/>
            <exclusion groupId="org.slf4j" artifactId="slf4j-api"/>
          </dependency>
          <dependency groupId="org.apache.hadoop" artifactId="hadoop-minicluster" version="1.0.3" scope="provided">
            <exclusion groupId="asm" artifactId="asm"/> <!-- this is the outdated version 3.1 -->
            <exclusion groupId="org.slf4j" artifactId="slf4j-api"/>
            <exclusion groupId="org.codehaus.jackson" artifactId="jackson-mapper-asl"/>
          </dependency>
          <dependency groupId="net.java.dev.jna" artifactId="jna" version="5.6.0"/>

          <dependency groupId="org.jacoco" artifactId="org.jacoco.agent" version="${jacoco.version}" scope="test"/>
          <dependency groupId="org.jacoco" artifactId="org.jacoco.ant" version="${jacoco.version}" scope="test"/>

          <dependency groupId="org.jboss.byteman" artifactId="byteman-install" version="${byteman.version}" scope="provided"/>
          <dependency groupId="org.jboss.byteman" artifactId="byteman" version="${byteman.version}" scope="provided"/>
          <dependency groupId="org.jboss.byteman" artifactId="byteman-submit" version="${byteman.version}" scope="provided"/>
          <dependency groupId="org.jboss.byteman" artifactId="byteman-bmunit" version="${byteman.version}" scope="provided"/>

          <dependency groupId="net.bytebuddy" artifactId="byte-buddy" version="${bytebuddy.version}" />
          <dependency groupId="net.bytebuddy" artifactId="byte-buddy-agent" version="${bytebuddy.version}" />

          <dependency groupId="org.openjdk.jmh" artifactId="jmh-core" version="1.21" scope="test"/>
          <dependency groupId="org.openjdk.jmh" artifactId="jmh-generator-annprocess" version="1.21" scope="test"/>

          <dependency groupId="org.apache.ant" artifactId="ant-junit" version="1.10.12" scope="test"/>

          <dependency groupId="org.apache.cassandra" artifactId="cassandra-all" version="${version}" />
          <dependency groupId="io.dropwizard.metrics" artifactId="metrics-core" version="3.1.5" />
          <dependency groupId="io.dropwizard.metrics" artifactId="metrics-jvm" version="3.1.5" />
          <dependency groupId="io.dropwizard.metrics" artifactId="metrics-logback" version="3.1.5" />
          <dependency groupId="com.addthis.metrics" artifactId="reporter-config3" version="3.0.3">
            <exclusion groupId="org.hibernate" artifactId="hibernate-validator" />
           </dependency>
          <dependency groupId="org.mindrot" artifactId="jbcrypt" version="0.4" />
          <dependency groupId="io.airlift" artifactId="airline" version="0.8">
            <exclusion groupId="com.google.code.findbugs" artifactId="jsr305" />
           </dependency>
          <dependency groupId="io.netty" artifactId="netty-bom" version="4.1.58.Final" type="pom" scope="provided"/>
          <dependency groupId="io.netty" artifactId="netty-all" version="4.1.58.Final" />
          <dependency groupId="io.netty" artifactId="netty-tcnative-boringssl-static" version="2.0.36.Final"/>
          <dependency groupId="net.openhft" artifactId="chronicle-queue" version="${chronicle-queue.version}">
            <exclusion groupId="com.sun" artifactId="tools" />
          </dependency>
          <dependency groupId="net.openhft" artifactId="chronicle-core" version="${chronicle-core.version}">
            <exclusion groupId="net.openhft" artifactId="chronicle-analytics" />
            <exclusion groupId="org.jetbrains" artifactId="annotations" />
          </dependency>
          <dependency groupId="net.openhft" artifactId="chronicle-bytes" version="${chronicle-bytes.version}">
            <exclusion groupId="org.jetbrains" artifactId="annotations" />
          </dependency>
          <dependency groupId="net.openhft" artifactId="chronicle-wire" version="${chronicle-wire.version}">
            <exclusion groupId="net.openhft" artifactId="compiler" />
          </dependency>
          <dependency groupId="net.openhft" artifactId="chronicle-threads" version="${chronicle-threads.version}">
            <exclusion groupId="net.openhft" artifactId="affinity" />
            <!-- Exclude JNA here, as we want to avoid breaking consumers of the cassandra-all jar -->
            <exclusion groupId="net.java.dev.jna" artifactId="jna" />
            <exclusion groupId="net.java.dev.jna" artifactId="jna-platform" />
          </dependency>
          <dependency groupId="com.google.code.findbugs" artifactId="jsr305" version="2.0.2" scope="provided"/>
          <dependency groupId="com.clearspring.analytics" artifactId="stream" version="2.5.2">
            <exclusion groupId="it.unimi.dsi" artifactId="fastutil" />
          </dependency>
          <dependency groupId="com.datastax.cassandra" artifactId="cassandra-driver-core" version="3.11.0" classifier="shaded">
            <exclusion groupId="io.netty" artifactId="netty-buffer"/>
            <exclusion groupId="io.netty" artifactId="netty-codec"/>
            <exclusion groupId="io.netty" artifactId="netty-handler"/>
            <exclusion groupId="io.netty" artifactId="netty-transport"/>
            <exclusion groupId="org.slf4j" artifactId="slf4j-api"/>
            <exclusion groupId="com.github.jnr" artifactId="jnr-ffi"/>
            <exclusion groupId="com.github.jnr" artifactId="jnr-posix"/>
          </dependency>
          <dependency groupId="org.eclipse.jdt.core.compiler" artifactId="ecj" version="${ecj.version}" />
          <dependency groupId="org.caffinitas.ohc" artifactId="ohc-core" version="${ohc.version}">
            <exclusion groupId="org.slf4j" artifactId="slf4j-api"/>
          </dependency>
          <dependency groupId="org.caffinitas.ohc" artifactId="ohc-core-j8" version="${ohc.version}" />
          <dependency groupId="net.ju-n.compile-command-annotations" artifactId="compile-command-annotations" version="1.2.0" scope="provided"/>
          <dependency groupId="org.fusesource" artifactId="sigar" version="1.6.4">
            <exclusion groupId="log4j" artifactId="log4j"/>
          </dependency>
          <dependency groupId="com.carrotsearch" artifactId="hppc" version="0.8.1" />
          <dependency groupId="de.jflex" artifactId="jflex" version="${jflex.version}">
            <exclusion groupId="org.apache.ant" artifactId="ant"/>
          </dependency>
          <dependency groupId="com.github.rholder" artifactId="snowball-stemmer" version="1.3.0.581.1" />
          <dependency groupId="com.googlecode.concurrent-trees" artifactId="concurrent-trees" version="2.4.0" />
          <dependency groupId="com.github.ben-manes.caffeine" artifactId="caffeine" version="2.5.6" />
          <dependency groupId="org.jctools" artifactId="jctools-core" version="3.1.0"/>
          <dependency groupId="org.ow2.asm" artifactId="asm" version="${asm.version}"/>
          <dependency groupId="org.ow2.asm" artifactId="asm-tree" version="${asm.version}" scope="test"/>
          <dependency groupId="org.ow2.asm" artifactId="asm-commons" version="${asm.version}" scope="test"/>
          <dependency groupId="org.gridkit.jvmtool" artifactId="sjk-cli" version="0.14"/>
          <dependency groupId="org.gridkit.jvmtool" artifactId="sjk-core" version="0.14">
            <exclusion groupId="org.gridkit.jvmtool" artifactId="sjk-hflame"/>
            <exclusion groupId="org.perfkit.sjk.parsers" artifactId="sjk-hflame"/>
            <exclusion groupId="org.perfkit.sjk.parsers" artifactId="sjk-jfr-standalone"/>
            <exclusion groupId="org.perfkit.sjk.parsers" artifactId="sjk-nps"/>
            <exclusion groupId="org.perfkit.sjk.parsers" artifactId="sjk-jfr5"/>
            <exclusion groupId="org.perfkit.sjk.parsers" artifactId="sjk-jfr6"/>
          </dependency>
          <dependency groupId="org.gridkit.jvmtool" artifactId="sjk-stacktrace" version="0.14"/>
          <dependency groupId="org.gridkit.jvmtool" artifactId="mxdump" version="0.14"/>
          <dependency groupId="org.gridkit.lab" artifactId="jvm-attach-api" version="1.5"/>
          <dependency groupId="org.gridkit.jvmtool" artifactId="sjk-json" version="0.14"/>
          <dependency groupId="com.beust" artifactId="jcommander" version="1.30"/>
          <dependency groupId="org.psjava" artifactId="psjava" version="0.1.19"/>
          <dependency groupId="javax.inject" artifactId="javax.inject" version="1"/>
          <dependency groupId="com.google.j2objc" artifactId="j2objc-annotations" version="1.3"/>
          <!-- adding this dependency is necessary for assertj. When updating assertj, need to also update the version of
             this that the new assertj's `assertj-parent-pom` depends on. -->
          <dependency groupId="org.junit" artifactId="junit-bom" version="5.6.0" type="pom" scope="test"/>
          <!-- when updating assertj, make sure to also update the corresponding junit-bom dependency -->
          <dependency groupId="org.assertj" artifactId="assertj-core" version="3.15.0" scope="provided"/>
          <dependency groupId="org.awaitility" artifactId="awaitility" version="4.0.3"  scope="test">
            <exclusion groupId="org.hamcrest" artifactId="hamcrest"/>
          </dependency>
          <dependency groupId="org.hamcrest" artifactId="hamcrest" version="2.2" scope="test"/>
        </dependencyManagement>
        <developer id="adelapena" name="Andres de la Peña"/>
        <developer id="alakshman" name="Avinash Lakshman"/>
        <developer id="aleksey" name="Aleksey Yeschenko"/>
        <developer id="amorton" name="Aaron Morton"/>
        <developer id="aweisberg" name="Ariel Weisberg"/>
        <developer id="bdeggleston" name="Blake Eggleston"/>
        <developer id="benedict" name="Benedict Elliott Smith"/>
        <developer id="benjamin" name="Benjamin Lerer"/>
        <developer id="blambov" name="Branimir Lambov"/>
        <developer id="brandonwilliams" name="Brandon Williams"/>
        <developer id="carl" name="Carl Yeksigian"/>
        <developer id="dbrosius" name="David Brosiusd"/>
        <developer id="dikang" name="Dikang Gu"/>
        <developer id="eevans" name="Eric Evans"/>
        <developer id="edimitrova" name="Ekaterina Dimitrova"/>
        <developer id="gdusbabek" name="Gary Dusbabek"/>
        <developer id="goffinet" name="Chris Goffinet"/>
        <developer id="ifesdjeen" name="Alex Petrov"/>
        <developer id="jaakko" name="Laine Jaakko Olavi"/>
        <developer id="jake" name="T Jake Luciani"/>
        <developer id="jasonbrown" name="Jason Brown"/>
        <developer id="jbellis" name="Jonathan Ellis"/>
        <developer id="jfarrell" name="Jake Farrell"/>
        <developer id="jjirsa" name="Jeff Jirsa"/>
        <developer id="jkni" name="Joel Knighton"/>
        <developer id="jmckenzie" name="Josh McKenzie"/>
        <developer id="johan" name="Johan Oskarsson"/>
        <developer id="junrao" name="Jun Rao"/>
        <developer id="jzhuang" name="Jay Zhuang"/>
        <developer id="kohlisankalp" name="Sankalp Kohli"/>
        <developer id="marcuse" name="Marcus Eriksson"/>
        <developer id="mck" name="Michael Semb Wever"/>
        <developer id="mishail" name="Mikhail Stepura"/>
        <developer id="mshuler" name="Michael Shuler"/>
        <developer id="paulo" name="Paulo Motta"/>
        <developer id="pmalik" name="Prashant Malik"/>
        <developer id="rstupp" name="Robert Stupp"/>
        <developer id="scode" name="Peter Schuller"/>
        <developer id="beobal" name="Sam Tunnicliffe"/>
        <developer id="slebresne" name="Sylvain Lebresne"/>
        <developer id="stefania" name="Stefania Alborghetti"/>
        <developer id="tylerhobbs" name="Tyler Hobbs"/>
        <developer id="vijay" name="Vijay Parthasarathy"/>
        <developer id="xedin" name="Pavel Yaskevich"/>
        <developer id="yukim" name="Yuki Morishita"/>
        <developer id="zznate" name="Nate McCall"/>
      </artifact:pom>

      <!-- each dependency set then defines the subset of the dependencies for that dependency set -->
      <artifact:pom id="build-deps-pom"
                    artifactId="cassandra-build-deps">
        <parent groupId="org.apache.cassandra"
                artifactId="cassandra-parent"
                version="${version}"
                relativePath="${final.name}-parent.pom"/>
        <dependency groupId="junit" artifactId="junit"/>
        <dependency groupId="commons-io" artifactId="commons-io"/>
        <dependency groupId="org.mockito" artifactId="mockito-core"/>
        <dependency groupId="org.quicktheories" artifactId="quicktheories"/>
        <dependency groupId="org.reflections" artifactId="reflections"/>
        <dependency groupId="com.google.code.java-allocation-instrumenter" artifactId="java-allocation-instrumenter" version="${allocation-instrumenter.version}"/>
        <dependency groupId="org.apache.cassandra" artifactId="dtest-api"/>
        <dependency groupId="org.openjdk.jmh" artifactId="jmh-core"/>
        <dependency groupId="org.openjdk.jmh" artifactId="jmh-generator-annprocess"/>
        <dependency groupId="org.apache.ant" artifactId="ant-junit"/>
        <!-- adding this dependency is necessary for assertj. When updating assertj, need to also update the version of
             this that the new assertj's `assertj-parent-pom` depends on. -->
        <dependency groupId="org.junit" artifactId="junit-bom" type="pom"/>
        <dependency groupId="org.awaitility" artifactId="awaitility"/>
        <dependency groupId="org.hamcrest" artifactId="hamcrest"/>
        <!-- coverage debs -->
        <dependency groupId="org.jacoco" artifactId="org.jacoco.agent"/>
        <dependency groupId="org.jacoco" artifactId="org.jacoco.ant"/>
      </artifact:pom>

      <!-- now the pom's for artifacts being deployed to Maven Central -->
      <artifact:pom id="all-pom"
                    artifactId="cassandra-all"
                    url="https://cassandra.apache.org"
                    name="Apache Cassandra">
        <parent groupId="org.apache.cassandra"
                artifactId="cassandra-parent"
                version="${version}"
                relativePath="${final.name}-parent.pom"/>
        <scm connection="${scm.connection}" developerConnection="${scm.developerConnection}" url="${scm.url}"/>
        <dependency groupId="org.xerial.snappy" artifactId="snappy-java"/>
        <dependency groupId="org.lz4" artifactId="lz4-java"/>
        <dependency groupId="com.ning" artifactId="compress-lzf"/>
        <dependency groupId="com.google.guava" artifactId="guava"/>
        <dependency groupId="commons-cli" artifactId="commons-cli"/>
        <dependency groupId="commons-codec" artifactId="commons-codec"/>
        <dependency groupId="org.apache.commons" artifactId="commons-lang3"/>
        <dependency groupId="org.apache.commons" artifactId="commons-math3"/>
        <dependency groupId="org.antlr" artifactId="antlr" scope="provided"/>
        <dependency groupId="org.antlr" artifactId="ST4"/>
        <dependency groupId="org.antlr" artifactId="antlr-runtime"/>
        <dependency groupId="org.slf4j" artifactId="slf4j-api"/>
        <dependency groupId="org.slf4j" artifactId="log4j-over-slf4j"/>
        <dependency groupId="org.slf4j" artifactId="jcl-over-slf4j"/>
        <dependency groupId="com.fasterxml.jackson.core" artifactId="jackson-core"/>
        <dependency groupId="com.fasterxml.jackson.core" artifactId="jackson-databind"/>
        <dependency groupId="com.fasterxml.jackson.core" artifactId="jackson-annotations"/>
        <dependency groupId="com.googlecode.json-simple" artifactId="json-simple"/>
        <dependency groupId="com.boundary" artifactId="high-scale-lib"/>
        <dependency groupId="org.yaml" artifactId="snakeyaml"/>
        <dependency groupId="org.mindrot" artifactId="jbcrypt"/>
        <dependency groupId="io.airlift" artifactId="airline"/>
        <dependency groupId="io.dropwizard.metrics" artifactId="metrics-core"/>
        <dependency groupId="io.dropwizard.metrics" artifactId="metrics-jvm"/>
        <dependency groupId="io.dropwizard.metrics" artifactId="metrics-logback"/>
        <dependency groupId="com.addthis.metrics" artifactId="reporter-config3"/>
        <dependency groupId="com.clearspring.analytics" artifactId="stream"/>

        <dependency groupId="ch.qos.logback" artifactId="logback-core"/>
        <dependency groupId="ch.qos.logback" artifactId="logback-classic"/>

        <!-- don't need hadoop classes to run, but if you use the hadoop stuff -->
        <dependency groupId="org.apache.hadoop" artifactId="hadoop-core" optional="true"/>
        <dependency groupId="org.apache.hadoop" artifactId="hadoop-minicluster" optional="true"/>

        <!-- don't need the Java Driver to run, but if you use the hadoop stuff or UDFs -->
        <dependency groupId="com.datastax.cassandra" artifactId="cassandra-driver-core" classifier="shaded" optional="true"/>
          <!-- don't need jna to run, but nice to have -->
        <dependency groupId="net.java.dev.jna" artifactId="jna"/>

        <!-- don't need jamm unless running a server in which case it needs to be a -javagent to be used anyway -->
        <dependency groupId="com.github.jbellis" artifactId="jamm"/>

        <dependency groupId="io.netty" artifactId="netty-bom"  type="pom"  />
        <dependency groupId="io.netty" artifactId="netty-all"/>
        <dependency groupId="net.openhft" artifactId="chronicle-queue"/>
        <dependency groupId="net.openhft" artifactId="chronicle-core"/>
        <dependency groupId="net.openhft" artifactId="chronicle-bytes"/>
        <dependency groupId="net.openhft" artifactId="chronicle-wire"/>
        <dependency groupId="net.openhft" artifactId="chronicle-threads"/>
        <dependency groupId="org.fusesource" artifactId="sigar"/>
        <dependency groupId="org.eclipse.jdt.core.compiler" artifactId="ecj"/>
        <dependency groupId="org.caffinitas.ohc" artifactId="ohc-core"/>
        <dependency groupId="org.caffinitas.ohc" artifactId="ohc-core-j8"/>
        <dependency groupId="com.github.ben-manes.caffeine" artifactId="caffeine" />
        <dependency groupId="org.jctools" artifactId="jctools-core"/>
        <dependency groupId="org.ow2.asm" artifactId="asm" />
        <dependency groupId="com.carrotsearch" artifactId="hppc" />
        <dependency groupId="org.gridkit.jvmtool" artifactId="sjk-cli" />
        <dependency groupId="org.gridkit.jvmtool" artifactId="sjk-core" />
        <dependency groupId="org.gridkit.jvmtool" artifactId="sjk-stacktrace" />
        <dependency groupId="org.gridkit.jvmtool" artifactId="mxdump" />
        <dependency groupId="org.gridkit.lab" artifactId="jvm-attach-api" />
        <dependency groupId="com.beust" artifactId="jcommander" />
        <dependency groupId="org.gridkit.jvmtool" artifactId="sjk-json"/>
        <dependency groupId="com.github.luben" artifactId="zstd-jni"/>
        <dependency groupId="org.psjava" artifactId="psjava"/>
        <dependency groupId="io.netty" artifactId="netty-tcnative-boringssl-static"/>
        <dependency groupId="javax.inject" artifactId="javax.inject"/>
        <dependency groupId="com.google.j2objc" artifactId="j2objc-annotations"/>
        <dependency groupId="org.hdrhistogram" artifactId="HdrHistogram"/>

        <!-- sasi deps -->
        <dependency groupId="de.jflex" artifactId="jflex" />
        <dependency groupId="com.github.rholder" artifactId="snowball-stemmer" />
        <dependency groupId="com.googlecode.concurrent-trees" artifactId="concurrent-trees" />

        <!-- compile tools -->
        <dependency groupId="com.google.code.findbugs" artifactId="jsr305"/>
        <dependency groupId="net.ju-n.compile-command-annotations" artifactId="compile-command-annotations"/>
        <dependency groupId="org.assertj" artifactId="assertj-core"/>
        <dependency groupId="org.jboss.byteman" artifactId="byteman-install"/>
        <dependency groupId="org.jboss.byteman" artifactId="byteman"/>
        <dependency groupId="org.jboss.byteman" artifactId="byteman-submit"/>
        <dependency groupId="org.jboss.byteman" artifactId="byteman-bmunit"/>
      </artifact:pom>
    </target>

    <!-- deprecated: legacy compatibility for build scripts in other repositories -->
    <target name="maven-ant-tasks-retrieve-build" depends="resolver-retrieve-build"/>

    <target name="echo-base-version">
        <echo message="${base.version}" />
    </target>

    <!-- create properties file with C version -->
    <target name="createVersionPropFile">
      <taskdef name="propertyfile" classname="org.apache.tools.ant.taskdefs.optional.PropertyFile"/>
      <mkdir dir="${version.properties.dir}"/>
      <propertyfile file="${version.properties.dir}/version.properties">
        <entry key="CassandraVersion" value="${version}"/>
      </propertyfile>
    </target>

    <target name="test-run" depends="jar"
            description="Run in test mode.  Not for production use!">
      <java classname="org.apache.cassandra.service.CassandraDaemon" fork="true">
        <classpath>
          <path refid="cassandra.classpath.test"/>
          <pathelement location="${test.conf}"/>
        </classpath>
        <jvmarg value="-Dstorage-config=${test.conf}"/>
        <jvmarg value="-javaagent:${build.lib}/jamm-${jamm.version}.jar" />
        <jvmarg value="-ea"/>
        <jvmarg line="${java11-jvmargs}"/>
      </java>
    </target>

    <!--
        The build target builds all the .class files
    -->
    <target name="build" depends="resolver-retrieve-build,build-project" description="Compile Cassandra classes"/>
    <target name="codecoverage" depends="jacoco-run,jacoco-report" description="Create code coverage report"/>

    <target name="_build_java">
        <!-- Note: we cannot use javac's 'release' option, as that does not allow accessing sun.misc.Unsafe nor
        Nashorn's ClassFilter class as any javac modules option is invalid for relase 8. -->
        <echo message="Compiling for Java ${target.version}..."/>
        <javac
               debug="true" debuglevel="${debuglevel}" encoding="utf-8"
               destdir="${build.classes.main}" includeantruntime="false" source="${source.version}" target="${target.version}">
            <src path="${build.src.java}"/>
            <src path="${build.src.gen-java}"/>
            <compilerarg value="-XDignore.symbol.file"/>
            <compilerarg line="${jdk11-javac-exports}"/>
            <classpath>
                <path refid="cassandra.classpath"/>
            </classpath>
        </javac>
    </target>

    <target depends="init,gen-cql3-grammar,generate-cql-html,generate-jflex-java,rat-check"
            name="build-project">
        <echo message="${ant.project.name}: ${ant.file}"/>
        <!-- Order matters! -->
        <antcall target="_build_java"/>
        <antcall target="createVersionPropFile"/>
        <copy todir="${build.classes.main}">
            <fileset dir="${build.src.resources}" />
        </copy>
        <copy todir="${basedir}/conf" file="${build.classes.main}/META-INF/hotspot_compiler"/>
    </target>

    <!-- Stress build file -->
    <property name="stress.build.src" value="${basedir}/tools/stress/src" />
    <property name="stress.test.src" value="${basedir}/tools/stress/test/unit" />
    <property name="stress.build.classes" value="${build.classes}/stress" />
    <property name="stress.test.classes" value="${build.dir}/test/stress-classes" />
    <property name="stress.manifest" value="${stress.build.classes}/MANIFEST.MF" />

    <target name="stress-build-test" depends="stress-build" description="Compile stress tests">
        <javac debug="true" debuglevel="${debuglevel}" destdir="${stress.test.classes}"
               source="${source.version}" target="${target.version}"
               includeantruntime="false" encoding="utf-8">
            <classpath>
                <path refid="cassandra.classpath.test"/>
                <pathelement location="${stress.build.classes}" />
            </classpath>
            <src path="${stress.test.src}"/>
        </javac>
    </target>

    <target name="stress-build" depends="build" description="build stress tool">
        <antcall target="_stress_build"/>
    </target>

    <target name="_stress_build">
        <mkdir dir="${stress.build.classes}" />
        <javac compiler="modern" debug="true" debuglevel="${debuglevel}"
               source="${source.version}" target="${target.version}"
               encoding="utf-8" destdir="${stress.build.classes}" includeantruntime="true">
            <src path="${stress.build.src}" />
            <classpath>
                <path refid="cassandra.classpath" />
            </classpath>
        </javac>
        <copy todir="${stress.build.classes}">
            <fileset dir="${stress.build.src}/resources" />
        </copy>
    </target>

    <target name="stress-test" depends="stress-build-test, build-test" description="Runs stress tests">
        <testmacro inputdir="${stress.test.src}"
                       timeout="${test.timeout}">
        </testmacro>
    </target>

    <!-- Use this with an FQDN for test class, and an optional csv list of methods like this:
      ant stress-test-some -Dtest.name=org.apache.cassandra.stress.generate.DistributionGaussianTest
      ant stress-test-some -Dtest.name=org.apache.cassandra.stress.generate.DistributionGaussianTest -Dtest.methods=simpleGaussian
    -->
    <target name="stress-test-some" depends="stress-build-test, build-test" description="Runs stress tests">
        <testmacro inputdir="${stress.test.src}"
                       timeout="${test.timeout}">
          <test unless:blank="${test.methods}" name="${test.name}" methods="${test.methods}" outfile="build/test/output/TEST-${test.name}-${test.methods}"/>
          <test if:blank="${test.methods}" name="${test.name}" outfile="build/test/output/TEST-${test.name}"/>
        </testmacro>
    </target>

    <!--
        fqltool build file
        -->
    <property name="fqltool.build.src" value="${basedir}/tools/fqltool/src" />
    <property name="fqltool.test.src" value="${basedir}/tools/fqltool/test/unit" />
    <property name="fqltool.build.classes" value="${build.classes}/fqltool" />
    <property name="fqltool.test.classes" value="${build.dir}/test/fqltool-classes" />
    <property name="fqltool.manifest" value="${fqltool.build.classes}/MANIFEST.MF" />

    <target name="fqltool-build-test" depends="fqltool-build" description="Compile fqltool tests">
        <javac debug="true" debuglevel="${debuglevel}" destdir="${fqltool.test.classes}"
               source="${source.version}" target="${target.version}"
               includeantruntime="false" encoding="utf-8">
            <classpath>
                <path refid="cassandra.classpath.test"/>
                <pathelement location="${fqltool.build.classes}" />
            </classpath>
            <src path="${fqltool.test.src}"/>
        </javac>
    </target>

    <target name="fqltool-build" depends="build" description="build fqltool">
        <antcall target="_fqltool_build"/>
    </target>

    <target name="_fqltool_build">
        <mkdir dir="${fqltool.build.classes}" />
        <javac compiler="modern" debug="true" debuglevel="${debuglevel}"
               source="${source.version}" target="${target.version}"
               encoding="utf-8" destdir="${fqltool.build.classes}" includeantruntime="true">
            <src path="${fqltool.build.src}" />
            <classpath>
                <path refid="cassandra.classpath" />
            </classpath>
        </javac>
    </target>

    <target name="fqltool-test" depends="fqltool-build-test, build-test" description="Runs fqltool tests">
        <testmacro inputdir="${fqltool.test.src}"
                       timeout="${test.timeout}">
        </testmacro>
    </target>

    <target name="_write-poms" depends="maven-declare-dependencies">
        <artifact:writepom pomRefId="parent-pom" file="${build.dir}/${final.name}-parent.pom"/>
        <artifact:writepom pomRefId="all-pom" file="${build.dir}/${final.name}.pom"/>
        <artifact:writepom pomRefId="build-deps-pom" file="${build.dir}/tmp-${final.name}-deps.pom"/>
    </target>

    <target name="write-poms" unless="without.maven">
        <antcall target="_write-poms" />
    </target>

    <!--
        The jar target makes cassandra.jar output.
    -->
    <target name="_main-jar"
            depends="build"
            description="Assemble Cassandra JAR files">
      <mkdir dir="${build.classes.main}/META-INF" />
      <copy file="LICENSE.txt"
            tofile="${build.classes.main}/META-INF/LICENSE.txt"/>
      <copy file="NOTICE.txt"
            tofile="${build.classes.main}/META-INF/NOTICE.txt"/>

      <!-- Main Jar -->
      <jar jarfile="${build.dir}/${final.name}.jar">
        <fileset dir="${build.classes.main}">
        </fileset>
        <manifest>
        <!-- <section name="org/apache/cassandra/infrastructure"> -->
          <attribute name="Multi-Release" value="true"/>
          <attribute name="Implementation-Title" value="Cassandra"/>
          <attribute name="Implementation-Version" value="${version}"/>
          <attribute name="Implementation-Vendor" value="Apache"/>
        <!-- </section> -->
        </manifest>
      </jar>
    </target>
    <target name="jar"
            depends="_main-jar,build-test,stress-build,fqltool-build,write-poms"
            description="Assemble Cassandra JAR files">
      <!-- Stress jar -->
      <manifest file="${stress.manifest}">
        <attribute name="Built-By" value="Pavel Yaskevich"/>
        <attribute name="Main-Class" value="org.apache.cassandra.stress.Stress"/>
      </manifest>
      <mkdir dir="${stress.build.classes}/META-INF" />
      <mkdir dir="${build.dir}/tools/lib/" />
      <jar destfile="${build.dir}/tools/lib/stress.jar" manifest="${stress.manifest}">
        <fileset dir="${stress.build.classes}"/>
      </jar>
      <!-- fqltool jar -->
      <manifest file="${fqltool.manifest}">
        <attribute name="Built-By" value="Marcus Eriksson"/>
        <attribute name="Main-Class" value="org.apache.cassandra.fqltool.FullQueryLogTool"/>
      </manifest>
      <mkdir dir="${fqltool.build.classes}/META-INF" />
      <mkdir dir="${build.dir}/tools/lib/" />
      <jar destfile="${build.dir}/tools/lib/fqltool.jar" manifest="${stress.manifest}">
        <fileset dir="${fqltool.build.classes}"/>
      </jar>
    </target>

    <!--
        The javadoc-jar target makes cassandra-javadoc.jar output required for publishing to Maven central repository.
    -->
    <target name="javadoc-jar" depends="javadoc" unless="no-javadoc" description="Assemble Cassandra JavaDoc JAR file">
      <jar jarfile="${build.dir}/${final.name}-javadoc.jar" basedir="${javadoc.dir}"/>
      <!-- javadoc task always rebuilds so might as well remove the generated docs to prevent
           being pulled into the distribution by accident -->
      <delete quiet="true" dir="${javadoc.dir}"/>
    </target>

    <!--
        The sources-jar target makes cassandra-sources.jar output required for publishing to Maven central repository.
    -->
    <target name="sources-jar" depends="init" description="Assemble Cassandra Sources JAR file">
      <jar jarfile="${build.dir}/${final.name}-sources.jar">
        <fileset dir="${build.src.java}" defaultexcludes="yes">
          <include name="org/apache/**/*.java"/>
        </fileset>
        <fileset dir="${build.src.gen-java}" defaultexcludes="yes">
          <include name="org/apache/**/*.java"/>
        </fileset>
      </jar>
    </target>

    <target name="_artifacts-init" depends="jar">
      <mkdir dir="${dist.dir}"/>
      <!-- fix the control linefeed so that builds on windows works on linux -->
      <fixcrlf srcdir="bin" includes="**/*" eol="lf" eof="remove" />
      <fixcrlf srcdir="conf" includes="**/*" eol="lf" eof="remove" />
      <fixcrlf srcdir="tools/bin" includes="**/*" eol="lf" eof="remove" />
      <copy todir="${dist.dir}/lib">
        <fileset dir="${build.lib}"/>
        <fileset dir="${build.dir}">
          <include name="${final.name}.jar" />
        </fileset>
      </copy>
      <copy todir="${dist.dir}/doc" failonerror="false">
        <fileset dir="doc">
          <include name="cql3/CQL.html" />
          <include name="cql3/CQL.css" />
          <include name="SASI.md" />
        </fileset>
      </copy>
      <copy todir="${dist.dir}/doc/html" failonerror="false">
        <fileset dir="doc" />
        <globmapper from="build/html/*" to="*"/>
      </copy>
      <copy todir="${dist.dir}/bin">
        <fileset dir="bin"/>
      </copy>
      <copy todir="${dist.dir}/conf">
        <fileset dir="conf"/>
      </copy>
      <copy todir="${dist.dir}/pylib">
        <fileset dir="pylib">
          <include name="**" />
          <exclude name="**/*.pyc" />
        </fileset>
      </copy>
      <copy todir="${dist.dir}/">
        <fileset dir="${basedir}">
          <include name="*.txt" />
        </fileset>
      </copy>
      <copy todir="${dist.dir}/tools/bin">
        <fileset dir="${basedir}/tools/bin"/>
      </copy>
      <copy todir="${dist.dir}/tools/">
        <fileset dir="${basedir}/tools/">
            <include name="*.yaml"/>
    </fileset>
      </copy>
      <copy todir="${dist.dir}/tools/lib">
        <fileset dir="${build.dir}/tools/lib/">
            <include name="*.jar" />
        </fileset>
      </copy>
    </target>

    <!-- creates release tarballs -->
    <target name="artifacts" depends="_artifacts-init,gen-doc,sources-jar,javadoc-jar"
            description="Create Cassandra release artifacts">
      <tar compression="gzip" longfile="gnu"
        destfile="${build.dir}/${final.name}-bin.tar.gz">

        <!-- Everything but bin/ (default mode) -->
        <tarfileset dir="${dist.dir}" prefix="${final.name}">
          <include name="**"/>
          <exclude name="bin/*" />
          <exclude name="tools/bin/*"/>
        </tarfileset>
        <!-- Shell includes in bin/ (default mode) -->
        <tarfileset dir="${dist.dir}" prefix="${final.name}">
          <include name="bin/*.in.sh" />
          <include name="tools/bin/*.in.sh" />
        </tarfileset>
        <!-- Executable scripts in bin/ -->
        <tarfileset dir="${dist.dir}" prefix="${final.name}" mode="755">
          <include name="bin/*"/>
          <include name="tools/bin/*"/>
          <exclude name="bin/*.in.sh" />
          <exclude name="tools/bin/*.in.sh" />
        </tarfileset>
      </tar>

      <tar compression="gzip" longfile="gnu"
           destfile="${build.dir}/${final.name}-src.tar.gz">

        <tarfileset dir="${basedir}"
                    prefix="${final.name}-src">
          <include name="**"/>
          <exclude name="build/**" />
          <exclude name="lib/**" />
          <exclude name="src/gen-java/**" />
          <exclude name=".git/**" />
          <exclude name="venv/**" />
          <exclude name="src/resources/org/apache/cassandra/config/version.properties" />
          <exclude name="conf/hotspot_compiler" />
          <exclude name="doc/cql3/CQL.html" />
          <exclude name="doc/build/**" />
          <exclude name="bin/*" /> <!-- handled separately below -->
          <exclude name="tools/bin/*" /> <!-- handled separately below -->
          <!-- exclude python generated files -->
          <exclude name="**/__pycache__/**" />
          <!-- exclude Eclipse files -->
          <exclude name=".project" />
          <exclude name=".classpath" />
          <exclude name=".settings/**" />
          <exclude name=".externalToolBuilders/**" />
          <!-- exclude NetBeans files -->
          <exclude name="ide/nbproject/private/**" />
        </tarfileset>

        <!-- python driver -->
        <tarfileset dir="${basedir}" prefix="${final.name}-src">
          <include name="lib/cassandra-driver-internal-only-**" />
        </tarfileset>

        <!-- Shell includes in bin/ and tools/bin/ -->
        <tarfileset dir="${basedir}" prefix="${final.name}-src">
          <include name="bin/*.in.sh" />
          <include name="tools/bin/*.in.sh" />
        </tarfileset>
        <!-- Everything else (assumed to be scripts), is executable -->
        <tarfileset dir="${basedir}" prefix="${final.name}-src" mode="755">
          <include name="bin/*"/>
          <exclude name="bin/*.in.sh" />
          <include name="tools/bin/*"/>
          <exclude name="tools/bin/*.in.sh" />
        </tarfileset>
      </tar>

      <checksum forceOverwrite="yes" todir="${build.dir}" fileext=".sha256" algorithm="SHA-256">
        <fileset dir="${build.dir}">
          <include name="${final.name}-bin.tar.gz" />
          <include name="${final.name}-src.tar.gz" />
        </fileset>
      </checksum>
      <checksum forceOverwrite="yes" todir="${build.dir}" fileext=".sha512" algorithm="SHA-512">
        <fileset dir="${build.dir}">
          <include name="${final.name}-bin.tar.gz" />
          <include name="${final.name}-src.tar.gz" />
        </fileset>
      </checksum>
    </target>

  <target name="build-jmh" depends="build-test, jar" description="Create JMH uber jar">
      <jar jarfile="${build.test.dir}/deps.jar">
          <zipgroupfileset dir="${test.lib}/jars">
              <include name="*jmh*.jar"/>
              <include name="jopt*.jar"/>
              <include name="commons*.jar"/>
              <include name="junit*.jar"/>
              <include name="hamcrest*.jar"/>
          </zipgroupfileset>
          <zipgroupfileset dir="${build.lib}" includes="*.jar"/>
      </jar>
      <jar jarfile="${build.test.dir}/benchmarks.jar">
          <manifest>
              <attribute name="Main-Class" value="org.openjdk.jmh.Main"/>
          </manifest>
          <zipfileset src="${build.test.dir}/deps.jar" excludes="META-INF/*.SF" />
          <fileset dir="${build.classes.main}"/>
          <fileset dir="${test.classes}"/>
          <fileset dir="${test.conf}" />
      </jar>
  </target>

  <target name="build-test" depends="_main-jar,stress-build,fqltool-build,resolver-dist-lib" unless="no-build-test"
          description="Compile test classes">
    <antcall target="_build-test"/>
  </target>

  <target name="_build-test">
    <javac
     compiler="modern"
     debug="true"
     debuglevel="${debuglevel}"
     destdir="${test.classes}"
     includeantruntime="true"
     source="${source.version}"
     target="${target.version}"
     encoding="utf-8">
     <classpath>
        <path refid="cassandra.classpath.test"/>
        <pathelement location="${fqltool.build.classes}"/>
     </classpath>
     <compilerarg value="-XDignore.symbol.file"/>
     <src path="${test.unit.src}"/>
     <src path="${test.long.src}"/>
     <src path="${test.burn.src}"/>
     <src path="${test.memory.src}"/>
     <src path="${test.microbench.src}"/>
     <src path="${test.distributed.src}"/>
    </javac>

    <!-- Non-java resources needed by the test suite -->
    <copy todir="${test.classes}">
      <fileset dir="${test.resources}"/>
    </copy>
  </target>

  <!-- Run tests separately and report errors after and generate a junit report -->
  <macrodef name="testhelper">
    <attribute name="testdelegate"/>
    <sequential>
      <testhelper_ testdelegate="@{testdelegate}"/>
      <fail message="Some test(s) failed.">
        <condition>
            <and>
            <isset property="testfailed"/>
            <not>
              <isset property="ant.test.failure.ignore"/>
            </not>
          </and>
        </condition>
      </fail>
    </sequential>
  </macrodef>

  <!-- Run a list of junit tasks but don't track errors or generate a report after
       If a test fails the testfailed property will be set. All the tests are run using the testdelegate
       macro that is specified as an attribute and they will be run sequentially in this ant process -->
  <scriptdef name="testhelper_" language="javascript">
    <attribute name="testdelegate"/>
    <![CDATA[
        sep = project.getProperty("path.separator");
        all = project.getProperty("all-test-classes").split(sep);
        var p = project.createTask('sequential');
        for (i = 0; i < all.length; i++) {
            if (all[i] == undefined) continue;
            task = project.createTask( attributes.get("testdelegate") );
            task.setDynamicAttribute( "test.file.list", "" + all[i]);
            p.addTask(task);
        }
        p.perform();
    ]]>
  </scriptdef>

  <!-- Defines how to run a set of tests. If you change the defaults for attributes
       you should also update them in testmacro.,
       The two are split because the helper doesn't generate
       a junit report or fail on errors -->
  <macrodef name="testmacrohelper">
    <attribute name="inputdir" />
    <attribute name="timeout" default="${test.timeout}" />
    <attribute name="forkmode" default="perTest"/>
    <element name="optjvmargs" implicit="true" optional="true" />
    <attribute name="filter" default="**/${test.name}.java"/>
    <attribute name="exclude" default="" />
    <attribute name="filelist" default="" />
    <attribute name="testtag" default=""/>
    <attribute name="usejacoco" default="no"/>
    <attribute name="showoutput" default="false"/>

    <sequential>
      <condition property="additionalagent"
                 value="-javaagent:${build.dir.lib}/jars/jacocoagent.jar=destfile=${jacoco.partialexecfile}"
                 else="">
        <istrue value="${usejacoco}"/>
      </condition>
      <taskdef name="junit-timeout" classname="org.apache.cassandra.JStackJUnitTask">
        <classpath>
          <pathelement location="${test.classes}"/>
        </classpath>
      </taskdef>
      <mkdir dir="${build.test.dir}/cassandra"/>
      <mkdir dir="${build.test.dir}/output"/>
      <mkdir dir="${build.test.dir}/output/@{testtag}"/>
      <junit-timeout fork="on" forkmode="@{forkmode}" failureproperty="testfailed" maxmemory="1024m" timeout="@{timeout}" showoutput="@{showoutput}">
        <formatter classname="org.apache.cassandra.CassandraXMLJUnitResultFormatter" extension=".xml" usefile="true"/>
        <formatter classname="org.apache.cassandra.CassandraBriefJUnitResultFormatter" usefile="false"/>
        <jvmarg value="-Dstorage-config=${test.conf}"/>
        <jvmarg value="-Djava.awt.headless=true"/>
        <!-- Cassandra 3.0+ needs <jvmarg line="... ${additionalagent}" /> here! (not value=) -->
        <jvmarg line="-javaagent:${build.lib}/jamm-${jamm.version}.jar ${additionalagent}" />
        <jvmarg value="-ea"/>
        <jvmarg value="-Djava.io.tmpdir=${tmp.dir}"/>
        <jvmarg value="-Dcassandra.debugrefcount=true"/>
        <jvmarg value="-Xss256k"/>
        <!-- When we do classloader manipulation SoftReferences can cause memory leaks
             that can OOM our test runs. The next two settings informs our GC
             algorithm to limit the metaspace size and clean up SoftReferences
             more aggressively rather than waiting. See CASSANDRA-14922 for more details.
        -->
        <jvmarg value="-XX:SoftRefLRUPolicyMSPerMB=0" />
        <jvmarg value="-Dcassandra.test.driver.connection_timeout_ms=${test.driver.connection_timeout_ms}"/>
        <jvmarg value="-Dcassandra.test.driver.read_timeout_ms=${test.driver.read_timeout_ms}"/>
        <jvmarg value="-Dcassandra.memtable_row_overhead_computation_step=100"/>
        <jvmarg value="-Dcassandra.test.use_prepared=${cassandra.test.use_prepared}"/>
        <jvmarg value="-Dcassandra.test.sstableformatdevelopment=true"/>
        <!-- The first time SecureRandom initializes can be slow if it blocks on /dev/random -->
        <jvmarg value="-Djava.security.egd=file:/dev/urandom" />
        <jvmarg value="-Dcassandra.testtag=@{testtag}"/>
        <jvmarg value="-Dcassandra.keepBriefBrief=${cassandra.keepBriefBrief}" />
        <jvmarg value="-Dcassandra.strict.runtime.checks=true" />
        <jvmarg line="${java11-jvmargs}"/>
        <!-- disable shrinks in quicktheories CASSANDRA-15554 -->
        <jvmarg value="-DQT_SHRINKS=0"/>
        <jvmarg line="${test-jvmargs}" />
        <optjvmargs/>
        <!-- Uncomment to debug unittest, attach debugger to port 1416 -->
        <!--
        <jvmarg line="-agentlib:jdwp=transport=dt_socket,address=localhost:1416,server=y,suspend=y" />
        -->
        <classpath>
          <pathelement path="${java.class.path}"/>
          <pathelement location="${stress.build.classes}"/>
          <pathelement location="${fqltool.build.classes}"/>
          <path refid="cassandra.classpath.test" />
          <pathelement location="${test.classes}"/>
          <pathelement location="${stress.test.classes}"/>
          <pathelement location="${fqltool.test.classes}"/>
          <pathelement location="${test.conf}"/>
          <fileset dir="${test.lib}">
            <include name="**/*.jar" />
              <exclude name="**/ant-*.jar"/>
          </fileset>
        </classpath>
        <batchtest todir="${build.test.dir}/output/@{testtag}">
            <fileset dir="@{inputdir}" includes="@{filter}" excludes="@{exclude}"/>
            <filelist dir="@{inputdir}" files="@{filelist}"/>
        </batchtest>
      </junit-timeout>

      <delete quiet="true" failonerror="false" dir="${build.test.dir}/cassandra/commitlog"/>
      <delete quiet="true" failonerror="false" dir="${build.test.dir}/cassandra/cdc_raw"/>
      <delete quiet="true" failonerror="false" dir="${build.test.dir}/cassandra/data"/>
      <delete quiet="true" failonerror="false" dir="${build.test.dir}/cassandra/ssl_upload_tables"/>
      <delete quiet="true" failonerror="false" dir="${build.test.dir}/cassandra/system_data"/>
      <delete quiet="true" failonerror="false" dir="${build.test.dir}/cassandra/saved_caches"/>
      <delete quiet="true" failonerror="false" dir="${build.test.dir}/cassandra/hints"/>
    </sequential>
  </macrodef>

  <target name="testold" depends="build-test" description="Execute unit tests">
    <testmacro inputdir="${test.unit.src}" timeout="${test.timeout}">
      <jvmarg value="-Dlegacy-sstable-root=${test.data}/legacy-sstables"/>
      <jvmarg value="-Dinvalid-legacy-sstable-root=${test.data}/invalid-legacy-sstables"/>
      <jvmarg value="-Dcassandra.ring_delay_ms=1000"/>
      <jvmarg value="-Dcassandra.tolerate_sstable_size=true"/>
      <jvmarg value="-Dcassandra.skip_sync=true" />
    </testmacro>
    <fileset dir="${test.unit.src}" />
  </target>

  <!-- Will not generate a junit report or fail on error  -->
  <macrodef name="testlist">
    <attribute name="test.file.list"/>
    <sequential>
      <testmacrohelper inputdir="${test.dir}/${test.classlistprefix}" filelist="@{test.file.list}" exclude="**/*.java" timeout="${test.timeout}">
        <jvmarg value="-Dlegacy-sstable-root=${test.data}/legacy-sstables"/>
        <jvmarg value="-Dinvalid-legacy-sstable-root=${test.data}/invalid-legacy-sstables"/>
        <jvmarg value="-Dcassandra.ring_delay_ms=1000"/>
        <jvmarg value="-Dcassandra.tolerate_sstable_size=true"/>
        <jvmarg value="-Dcassandra.skip_sync=true" />
      </testmacrohelper>
    </sequential>
  </macrodef>

  <!-- Will not generate a junit report  -->
  <macrodef name="testlist-compression">
    <attribute name="test.file.list" />
    <sequential>
      <property name="compressed_yaml" value="${build.test.dir}/cassandra.compressed.yaml"/>
      <concat destfile="${compressed_yaml}">
          <fileset file="${test.conf}/cassandra.yaml"/>
          <fileset file="${test.conf}/commitlog_compression_${test.compression.algo}.yaml"/>
      </concat>
      <testmacrohelper inputdir="${test.unit.src}" filelist="@{test.file.list}"
                       exclude="**/*.java" timeout="${test.timeout}" testtag="compression">
        <jvmarg value="-Dlegacy-sstable-root=${test.data}/legacy-sstables"/>
        <jvmarg value="-Dinvalid-legacy-sstable-root=${test.data}/invalid-legacy-sstables"/>
        <jvmarg value="-Dcassandra.test.compression=true"/>
        <jvmarg value="-Dcassandra.test.compression.algo=${test.compression.algo}"/>
        <jvmarg value="-Dcassandra.ring_delay_ms=1000"/>
        <jvmarg value="-Dcassandra.tolerate_sstable_size=true"/>
        <jvmarg value="-Dcassandra.config=file:///${compressed_yaml}"/>
        <jvmarg value="-Dcassandra.skip_sync=true" />
      </testmacrohelper>
    </sequential>
  </macrodef>

  <macrodef name="testlist-cdc">
    <attribute name="test.file.list" />
    <sequential>
      <property name="cdc_yaml" value="${build.test.dir}/cassandra.cdc.yaml"/>
      <concat destfile="${cdc_yaml}">
        <fileset file="${test.conf}/cassandra.yaml"/>
        <fileset file="${test.conf}/cdc.yaml"/>
      </concat>
      <testmacrohelper inputdir="${test.unit.src}" filelist="@{test.file.list}"
                       exclude="**/*.java" timeout="${test.timeout}" testtag="cdc">
        <jvmarg value="-Dlegacy-sstable-root=${test.data}/legacy-sstables"/>
        <jvmarg value="-Dinvalid-legacy-sstable-root=${test.data}/invalid-legacy-sstables"/>
        <jvmarg value="-Dcassandra.ring_delay_ms=1000"/>
        <jvmarg value="-Dcassandra.tolerate_sstable_size=true"/>
        <jvmarg value="-Dcassandra.config=file:///${cdc_yaml}"/>
        <jvmarg value="-Dcassandra.skip_sync=true" />
      </testmacrohelper>
    </sequential>
  </macrodef>

  <macrodef name="testlist-system-keyspace-directory">
    <attribute name="test.file.list" />
    <sequential>
      <property name="system_keyspaces_directory_yaml" value="${build.test.dir}/cassandra.system.yaml"/>
      <concat destfile="${system_keyspaces_directory_yaml}">
        <fileset file="${test.conf}/cassandra.yaml"/>
        <fileset file="${test.conf}/system_keyspaces_directory.yaml"/>
      </concat>
      <testmacrohelper inputdir="${test.unit.src}" filelist="@{test.file.list}"
                       exclude="**/*.java" timeout="${test.timeout}" testtag="system_keyspace_directory">
        <jvmarg value="-Dlegacy-sstable-root=${test.data}/legacy-sstables"/>
        <jvmarg value="-Dinvalid-legacy-sstable-root=${test.data}/invalid-legacy-sstables"/>
        <jvmarg value="-Dcassandra.ring_delay_ms=1000"/>
        <jvmarg value="-Dcassandra.tolerate_sstable_size=true"/>
        <jvmarg value="-Dcassandra.config=file:///${system_keyspaces_directory_yaml}"/>
        <jvmarg value="-Dcassandra.skip_sync=true" />
      </testmacrohelper>
    </sequential>
  </macrodef>

  <!--
    Run named ant task with jacoco, such as "ant jacoco-run -Dtaskname=test"
    the target run must enable the jacoco agent if usejacoco is 'yes' -->
  <target name="jacoco-run" description="run named task with jacoco instrumentation">
    <condition property="runtask" value="${taskname}" else="test">
      <isset property="taskname"/>
    </condition>
    <antcall target="${runtask}">
      <param name="usejacoco" value="yes"/>
    </antcall>
  </target>

  <!-- Use this with an FQDN for test class, and an optional csv list of methods like this:
    ant testsome -Dtest.name=org.apache.cassandra.service.StorageServiceServerTest -Dtest.methods=testRegularMode,testGetAllRangesEmpty
  -->
  <target name="testsome" depends="build-test" description="Execute specific unit tests" >
    <testmacro inputdir="${test.unit.src}" timeout="${test.timeout}">
      <test unless:blank="${test.methods}" name="${test.name}" methods="${test.methods}" outfile="build/test/output/TEST-${test.name}-${test.methods}"/>
      <test if:blank="${test.methods}" name="${test.name}" outfile="build/test/output/TEST-${test.name}"/>
      <jvmarg value="-Dlegacy-sstable-root=${test.data}/legacy-sstables"/>
      <jvmarg value="-Dinvalid-legacy-sstable-root=${test.data}/invalid-legacy-sstables"/>
      <jvmarg value="-Dcassandra.ring_delay_ms=1000"/>
      <jvmarg value="-Dcassandra.tolerate_sstable_size=true"/>
      <jvmarg value="-Dcassandra.skip_sync=true" />
    </testmacro>
  </target>

  <!-- Use this with an FQDN for test class, and an optional csv list of methods like this:
    ant long-testsome -Dtest.name=org.apache.cassandra.cql3.ManyRowsTest
    ant long-testsome -Dtest.name=org.apache.cassandra.cql3.ManyRowsTest -Dtest.methods=testLargeCount
  -->
  <target name="long-testsome" depends="build-test" description="Execute specific long unit tests" >
    <testmacro inputdir="${test.long.src}" timeout="${test.long.timeout}">
      <test unless:blank="${test.methods}" name="${test.name}" methods="${test.methods}"/>
      <test if:blank="${test.methods}" name="${test.name}"/>
      <jvmarg value="-Dcassandra.ring_delay_ms=1000"/>
      <jvmarg value="-Dcassandra.tolerate_sstable_size=true"/>
    </testmacro>
  </target>

  <!-- Use this with an FQDN for test class, and an optional csv list of methods like this:
    ant burn-testsome -Dtest.name=org.apache.cassandra.utils.memory.LongBufferPoolTest
    ant burn-testsome -Dtest.name=org.apache.cassandra.utils.memory.LongBufferPoolTest -Dtest.methods=testPoolAllocateWithRecyclePartially
  -->
  <target name="burn-testsome" depends="build-test" description="Execute specific burn unit tests" >
    <testmacro inputdir="${test.burn.src}" timeout="${test.burn.timeout}">
      <test unless:blank="${test.methods}" name="${test.name}" methods="${test.methods}"/>
      <test if:blank="${test.methods}" name="${test.name}"/>
      <jvmarg value="-Dlogback.configurationFile=test/conf/logback-burntest.xml"/>
    </testmacro>
  </target>

  <target name="test-compression" depends="build-test,stress-build" description="Execute unit tests with sstable compression enabled">
    <path id="all-test-classes-path">
      <fileset dir="${test.unit.src}" includes="**/${test.name}.java" />
      <fileset dir="${test.distributed.src}" includes="**/${test.name}.java" />
    </path>
    <property name="all-test-classes" refid="all-test-classes-path"/>
    <testhelper testdelegate="testlist-compression" />
  </target>

  <target name="test-cdc" depends="build-test" description="Execute unit tests with change-data-capture enabled">
    <path id="all-test-classes-path">
      <fileset dir="${test.unit.src}" includes="**/${test.name}.java" />
    </path>
    <property name="all-test-classes" refid="all-test-classes-path"/>
    <testhelper testdelegate="testlist-cdc" />
  </target>

  <target name="test-system-keyspace-directory" depends="build-test" description="Execute unit tests with a system keyspaces directory configured">
    <path id="all-test-classes-path">
      <fileset dir="${test.unit.src}" includes="**/${test.name}.java" />
    </path>
    <property name="all-test-classes" refid="all-test-classes-path"/>
    <testhelper testdelegate="testlist-system-keyspace-directory" />
  </target>

  <target name="msg-ser-gen-test" depends="build-test" description="Generates message serializations">
    <testmacro inputdir="${test.unit.src}"
        timeout="${test.timeout}" filter="**/SerializationsTest.java">
      <jvmarg value="-Dcassandra.test-serialization-writes=True"/>
    </testmacro>
  </target>

  <target name="msg-ser-test" depends="build-test" description="Tests message serializations">
      <testmacro inputdir="${test.unit.src}" timeout="${test.timeout}"
               filter="**/SerializationsTest.java"/>
  </target>

  <target name="msg-ser-test-7" depends="build-test" description="Generates message serializations">
    <testmacro inputdir="${test.unit.src}"
        timeout="${test.timeout}" filter="**/SerializationsTest.java">
      <jvmarg value="-Dcassandra.version=0.7"/>
    </testmacro>
  </target>

  <target name="msg-ser-test-10" depends="build-test" description="Tests message serializations on 1.0 messages">
    <testmacro inputdir="${test.unit.src}"
        timeout="${test.timeout}" filter="**/SerializationsTest.java">
      <jvmarg value="-Dcassandra.version=1.0"/>
    </testmacro>
  </target>

  <target name="test-burn" depends="build-test" description="Execute functional tests">
    <testmacro inputdir="${test.burn.src}"
               timeout="${test.burn.timeout}">
    </testmacro>
  </target>

  <target name="long-test" depends="build-test" description="Execute functional tests">
    <testmacro inputdir="${test.long.src}"
               timeout="${test.long.timeout}">
      <jvmarg value="-Dcassandra.ring_delay_ms=1000"/>
      <jvmarg value="-Dcassandra.tolerate_sstable_size=true"/>
    </testmacro>
  </target>

  <target name="test-memory" depends="build-test" description="Execute functional tests">
      <testmacro inputdir="${test.memory.src}"
                 timeout="${test.memory.timeout}">
          <jvmarg value="-javaagent:${build.dir}/test/lib/jars/java-allocation-instrumenter-${allocation-instrumenter.version}.jar"/>
      </testmacro>
  </target>

  <target name="cql-test" depends="build-test" description="Execute CQL tests">
    <sequential>
      <echo message="running CQL tests"/>
      <mkdir dir="${build.test.dir}/cassandra"/>
      <mkdir dir="${build.test.dir}/output"/>
      <junit fork="on" forkmode="once" failureproperty="testfailed" maxmemory="1024m" timeout="${test.timeout}">
        <formatter type="brief" usefile="false"/>
        <jvmarg value="-Dstorage-config=${test.conf}"/>
        <jvmarg value="-Djava.awt.headless=true"/>
        <jvmarg value="-javaagent:${build.lib}/jamm-${jamm.version}.jar" />
        <jvmarg value="-ea"/>
        <jvmarg value="-Xss256k"/>
        <jvmarg value="-Dcassandra.memtable_row_overhead_computation_step=100"/>
        <jvmarg value="-Dcassandra.test.use_prepared=${cassandra.test.use_prepared}"/>
        <jvmarg value="-Dcassandra.skip_sync=true" />
        <classpath>
          <path refid="cassandra.classpath.test" />
          <pathelement location="${test.classes}"/>
          <pathelement location="${test.conf}"/>
          <fileset dir="${test.lib}">
            <include name="**/*.jar" />
          </fileset>
        </classpath>
        <batchtest todir="${build.test.dir}/output">
            <fileset dir="${test.unit.src}" includes="**/cql3/*Test.java">
                <contains text="CQLTester" casesensitive="yes"/>
            </fileset>
        </batchtest>
      </junit>
      <fail message="Some CQL test(s) failed.">
        <condition>
            <and>
            <isset property="testfailed"/>
            <not>
              <isset property="ant.test.failure.ignore"/>
            </not>
          </and>
        </condition>
      </fail>
    </sequential>
  </target>

  <!-- Use this with an simple class name for test class, and an optional csv list of methods like this:
      ant cql-test-some -Dtest.name=ListsTest
      ant cql-test-some -Dtest.name=ListsTest -Dtest.methods=testPrecisionTime_getNext_simple
    -->
  <target name="cql-test-some" depends="build-test" description="Execute specific CQL tests" >
    <sequential>
      <echo message="running ${test.methods} tests from ${test.name}"/>
      <mkdir dir="${build.test.dir}/cassandra"/>
      <mkdir dir="${build.test.dir}/output"/>
      <junit fork="on" forkmode="once" failureproperty="testfailed" maxmemory="1024m" timeout="${test.timeout}">
        <formatter type="brief" usefile="false"/>
        <jvmarg value="-Dstorage-config=${test.conf}"/>
        <jvmarg value="-Djava.awt.headless=true"/>
        <jvmarg value="-javaagent:${build.lib}/jamm-${jamm.version}.jar" />
        <jvmarg value="-ea"/>
        <jvmarg value="-Xss256k"/>
        <jvmarg value="-Dcassandra.test.use_prepared=${cassandra.test.use_prepared}"/>
        <jvmarg value="-Dcassandra.memtable_row_overhead_computation_step=100"/>
        <jvmarg value="-Dcassandra.skip_sync=true" />
        <classpath>
          <path refid="cassandra.classpath.test" />
          <pathelement location="${test.classes}"/>
          <pathelement location="${test.conf}"/>
          <fileset dir="${test.lib}">
            <include name="**/*.jar" />
          </fileset>
        </classpath>
        <test unless:blank="${test.methods}" name="org.apache.cassandra.cql3.${test.name}" methods="${test.methods}" todir="${build.test.dir}/output"/>
        <test if:blank="${test.methods}" name="org.apache.cassandra.cql3.${test.name}" todir="${build.test.dir}/output"/>
      </junit>
    </sequential>
  </target>

  <!-- Use JaCoCo ant extension without needing externally saved lib -->
  <target name="jacoco-init" depends="resolver-init">
    <typedef uri="antlib:org.jacoco.ant" classpathref="jacocoant.classpath"/>
  </target>

  <target name="jacoco-merge" depends="jacoco-init">
    <jacoco:merge destfile="${jacoco.finalexecfile}" xmlns:jacoco="antlib:org.jacoco.ant">
        <fileset dir="${jacoco.export.dir}" includes="*.exec,**/*.exec"/>
    </jacoco:merge>
  </target>

  <target name="jacoco-report" depends="jacoco-merge">
    <jacoco:report xmlns:jacoco="antlib:org.jacoco.ant">
      <executiondata>
        <file file="${jacoco.finalexecfile}" />
      </executiondata>
      <structure name="JaCoCo Cassandara Coverage Report">
        <classfiles>
          <fileset dir="${build.classes.main}">
            <include name="**/*.class"/>
          </fileset>
        </classfiles>
        <sourcefiles encoding="UTF-8">
          <dirset dir="${build.src}">
            <include name="java"/>
            <include name="gen-java"/>
          </dirset>
        </sourcefiles>
      </structure>
      <!-- to produce reports in different formats. -->
      <html destdir="${jacoco.export.dir}" />
      <csv destfile="${jacoco.export.dir}/report.csv" />
      <xml destfile="${jacoco.export.dir}/report.xml" />
    </jacoco:report>
  </target>

  <target name="jacoco-cleanup" description="Destroy JaCoCo exec data and reports">
    <delete file="${jacoco.partialexecfile}"/>
    <delete dir="${jacoco.export.dir}"/>
  </target>

  <target name="javadoc" depends="build" description="Create javadoc" unless="no-javadoc">
    <create-javadoc destdir="${javadoc.dir}">
      <filesets>
        <fileset dir="${build.src.java}" defaultexcludes="yes">
          <include name="org/apache/**/*.java"/>
        </fileset>
      </filesets>
    </create-javadoc>
   </target>

  <!-- Run tests and reports errors and generates a junit report after -->
  <macrodef name="testmacro">
    <attribute name="inputdir" />
    <attribute name="timeout" default="${test.timeout}" />
    <attribute name="forkmode" default="perTest"/>
    <attribute name="showoutput" default="true"/>
    <element name="optjvmargs" implicit="true" optional="true" />
    <attribute name="filter" default="**/${test.name}.java"/>
    <attribute name="exclude" default="" />
    <attribute name="filelist" default="" />
    <attribute name="testtag" default=""/>

    <sequential>
      <testmacrohelper inputdir="@{inputdir}" timeout="@{timeout}"
                       forkmode="@{forkmode}" filter="@{filter}"
                       exclude="@{exclude}" filelist="@{filelist}"
                       testtag="@{testtag}" showoutput="false" >
          <optjvmargs/>
      </testmacrohelper>
      <fail message="Some test(s) failed.">
        <condition>
            <and>
            <isset property="testfailed"/>
            <not>
              <isset property="ant.test.failure.ignore"/>
            </not>
          </and>
        </condition>
      </fail>
    </sequential>
  </macrodef>

  <target name="test" depends="eclipse-warnings,build-test" description="Test Runner">
    <path id="all-test-classes-path">
      <fileset dir="${test.unit.src}" includes="**/${test.name}.java" excludes="**/distributed/test/UpgradeTest*.java" />
    </path>
    <property name="all-test-classes" refid="all-test-classes-path"/>
    <testhelper testdelegate="testlist"/>
  </target>

  <target name="generate-test-report" description="Generates JUnit's HTML report from results already in build/output">
      <junitreport todir="${build.test.dir}">
        <fileset dir="${build.test.dir}/output">
          <include name="**/TEST-*.xml"/>
        </fileset>
        <report format="frames" todir="${build.test.dir}/junitreport"/>
      </junitreport>
  </target>

  <!-- run a list of tests as provided in -Dtest.classlistfile (or default of 'testnames.txt')
  The class list file should be one test class per line, with the path starting after test/unit
  e.g. org/apache/cassandra/hints/HintMessageTest.java -->
  <target name="testclasslist" depends="build-test" description="Run tests given in file -Dtest.classlistfile (one-class-per-line, e.g. org/apache/cassandra/db/SomeTest.java)">
    <path id="all-test-classes-path">
      <fileset dir="${test.dir}/${test.classlistprefix}" includesfile="${test.classlistfile}"/>
    </path>
    <property name="all-test-classes" refid="all-test-classes-path"/>
    <testhelper testdelegate="testlist"/>
  </target>
  <target name="testclasslist-compression" depends="build-test" description="Run tests given in file -Dtest.classlistfile (one-class-per-line, e.g. org/apache/cassandra/db/SomeTest.java)">
      <path id="all-test-classes-path">
          <fileset dir="${test.dir}/${test.classlistprefix}" includesfile="${test.classlistfile}"/>
      </path>
      <property name="all-test-classes" refid="all-test-classes-path"/>
      <testhelper testdelegate="testlist-compression"/>
  </target>
  <target name="testclasslist-cdc" depends="build-test" description="Run tests given in file -Dtest.classlistfile (one-class-per-line, e.g. org/apache/cassandra/db/SomeTest.java)">
      <path id="all-test-classes-path">
          <fileset dir="${test.dir}/${test.classlistprefix}" includesfile="${test.classlistfile}"/>
      </path>
      <property name="all-test-classes" refid="all-test-classes-path"/>
      <testhelper testdelegate="testlist-cdc"/>
  </target>
  <target name="testclasslist-system-keyspace-directory" depends="build-test" description="Run tests given in file -Dtest.classlistfile (one-class-per-line, e.g. org/apache/cassandra/db/SomeTest.java)">
      <path id="all-test-classes-path">
          <fileset dir="${test.dir}/${test.classlistprefix}" includesfile="${test.classlistfile}"/>
      </path>
      <property name="all-test-classes" refid="all-test-classes-path"/>
      <testhelper testdelegate="testlist-system-keyspace-directory"/>
  </target>

  <!-- Build a self-contained jar for e.g. remote execution; not currently used for running burn tests with this build script -->
  <target name="burn-test-jar" depends="build-test, build" description="Create dtest-compatible jar, including all dependencies">
      <jar jarfile="${build.dir}/burntest.jar">
          <zipgroupfileset dir="${build.lib}" includes="*.jar" excludes="META-INF/*.SF"/>
          <fileset dir="${build.classes.main}"/>
          <fileset dir="${test.classes}"/>
          <fileset dir="${test.conf}" excludes="logback*.xml"/>
          <fileset dir="${basedir}/conf" includes="logback*.xml"/>
          <zipgroupfileset dir="${build.dir.lib}/jars">
              <include name="junit*.jar"/>
          </zipgroupfileset>
      </jar>
  </target>

  <target name="dtest-jar" depends="build-test, build" description="Create dtest-compatible jar, including all dependencies">
      <jar jarfile="${build.dir}/dtest-${base.version}.jar">
          <zipgroupfileset dir="${build.lib}" includes="*.jar" excludes="META-INF/*.SF"/>
          <zipgroupfileset dir="${build.dir.lib}/jars" includes="javassist-*.jar,reflections-*.jar" excludes="META-INF/*.SF"/>
          <fileset dir="${build.classes.main}"/>
          <fileset dir="${test.classes}"/>
          <fileset dir="${test.conf}" />
      </jar>
  </target>

  <target name="test-jvm-dtest" depends="build-test" description="Execute in-jvm dtests">
    <testmacro inputdir="${test.distributed.src}" timeout="${test.distributed.timeout}" forkmode="once" showoutput="true" filter="**/test/*Test.java">
      <jvmarg value="-Dlogback.configurationFile=test/conf/logback-dtest.xml"/>
      <jvmarg value="-Dcassandra.ring_delay_ms=10000"/>
      <jvmarg value="-Dcassandra.tolerate_sstable_size=true"/>
      <jvmarg value="-Dcassandra.skip_sync=true" />
    </testmacro>
  </target>

  <target name="test-jvm-upgrade-dtest" depends="build-test" description="Execute in-jvm dtests">
    <testmacro inputdir="${test.distributed.src}" timeout="${test.distributed.timeout}" forkmode="once" showoutput="true" filter="**/upgrade/*Test.java">
      <jvmarg value="-Dlogback.configurationFile=test/conf/logback-dtest.xml"/>
      <jvmarg value="-Dcassandra.ring_delay_ms=10000"/>
      <jvmarg value="-Dcassandra.tolerate_sstable_size=true"/>
      <jvmarg value="-Dcassandra.skip_sync=true" />
    </testmacro>
  </target>

  <!-- Use this with an FQDN for test class, and an optional csv list of methods like this:
      ant test-jvm-dtest-some -Dtest.name=org.apache.cassandra.distributed.test.ResourceLeakTest -Dtest.methods=looperTest
    -->
  <target name="test-jvm-dtest-some" depends="build-test" description="Execute some in-jvm dtests">
    <testmacro inputdir="${test.distributed.src}" timeout="${test.distributed.timeout}" forkmode="once" showoutput="true">
      <test unless:blank="${test.methods}" name="${test.name}" methods="${test.methods}" outfile="build/test/output/TEST-${test.name}-${test.methods}"/>
      <test if:blank="${test.methods}" name="${test.name}" outfile="build/test/output/TEST-${test.name}"/>
      <jvmarg value="-Dlogback.configurationFile=test/conf/logback-dtest.xml"/>
      <jvmarg value="-Dcassandra.ring_delay_ms=10000"/>
      <jvmarg value="-Dcassandra.tolerate_sstable_size=true"/>
      <jvmarg value="-Dcassandra.skip_sync=true" />
    </testmacro>
  </target>

  <!-- run microbenchmarks suite -->
  <target name="microbench" depends="build-jmh">
      <java classname="org.openjdk.jmh.Main"
            fork="true"
            failonerror="true">
          <classpath>
              <path refid="cassandra.classpath.test" />
              <pathelement location="${test.classes}"/>
              <pathelement location="${test.conf}"/>
              <fileset dir="${test.lib}">
                  <include name="**/*.jar" />
              </fileset>
          </classpath>
          <arg value="-foe"/>
          <arg value="true"/>
          <arg value="-rf"/>
          <arg value="json"/>
          <arg value="-rff"/>
          <arg value="${build.test.dir}/jmh-result.json"/>
          <arg value="-v"/>
          <arg value="EXTRA"/>

          <!-- Broken: ZeroCopyStreamingBench,MutationBench,FastThreadLocalBench  (FIXME) -->
          <arg value="-e"/><arg value="ZeroCopyStreamingBench|MutationBench|FastThreadLocalBench"/>

          <arg value=".*microbench.*${benchmark.name}"/>
      </java>
  </target>

  <!-- run arbitrary mains in tests, for example to run the long running memory tests with lots of memory pressure
      ant run-main -Dmainclass=org.apache.cassandra.utils.memory.LongBufferPoolTest -Dvmargs="-Xmx30m -XX:-UseGCOverheadLimit"
  -->
  <target name="run-main" depends="build-test">
      <property name="mainclass" value="" />
      <property name="vmargs" value="" />
      <property name="args" value="" />
      <java classname="${mainclass}"
            fork="true"
            failonerror="true">
          <jvmarg value="-server" />
          <jvmarg value="-ea" />
          <jvmarg line="${vmargs}" />
          <arg line="${args}" />
          <classpath>
              <path refid="cassandra.classpath" />
              <pathelement location="${test.classes}"/>
              <pathelement location="${test.conf}"/>
              <fileset dir="${test.lib}">
                  <include name="**/*.jar" />
              </fileset>
          </classpath>
      </java>
  </target>

  <target name="_maybe_update_idea_to_java11" if="java.version.11">
    <replace file="${eclipse.project.name}.iml" token="JDK_1_8" value="JDK_11"/>
    <replace file=".idea/misc.xml" token="JDK_1_8" value="JDK_11"/>
    <replace file=".idea/misc.xml" token="1.8" value="11"/>
    <replaceregexp file=".idea/workspace.xml"
                   match="name=&quot;VM_PARAMETERS&quot; value=&quot;(.*)&quot;"
                   replace="name=&quot;VM_PARAMETERS&quot; value=&quot;\1 ${java11-jvmargs}&quot;"
                   byline="true"/>

      <echo file=".idea/compiler.xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="JavacSettings">
    <option name="ADDITIONAL_OPTIONS_STRING" value="--add-exports java.rmi/sun.rmi.registry=ALL-UNNAMED" />
  </component>
</project>]]></echo>
  </target>

  <!-- Generate IDEA project description files -->
  <target name="generate-idea-files" depends="init,maven-ant-tasks-init,resolver-dist-lib,gen-cql3-grammar,generate-jflex-java,createVersionPropFile" description="Generate IDEA files">
    <mkdir dir=".idea"/>
    <mkdir dir=".idea/libraries"/>
    <copy todir=".idea" overwrite="true">
        <fileset dir="ide/idea"/>
    </copy>
    <replace file=".idea/workspace.xml" token="trunk" value="${eclipse.project.name}"/>
    <copy tofile="${eclipse.project.name}.iml" file="ide/idea-iml-file.xml"/>
    <echo file=".idea/.name">Apache Cassandra ${eclipse.project.name}</echo>
    <echo file=".idea/modules.xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/]]>${eclipse.project.name}<![CDATA[.iml" filepath="$PROJECT_DIR$/]]>${eclipse.project.name}<![CDATA[.iml" />
    </modules>
  </component>
</project>]]></echo>
      <antcall target="_maybe_update_idea_to_java11"/>
  </target>

  <!-- Generate Eclipse project description files -->
  <target name="generate-eclipse-files" depends="build-test" description="Generate eclipse files">
    <echo file=".project"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
  <name>${eclipse.project.name}</name>
  <comment></comment>
  <projects>
  </projects>
  <buildSpec>
    <buildCommand>
      <name>org.eclipse.jdt.core.javabuilder</name>
    </buildCommand>
  </buildSpec>
  <natures>
    <nature>org.eclipse.jdt.core.javanature</nature>
  </natures>
</projectDescription>]]>
    </echo>
    <echo file=".classpath"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<classpath>
  <classpathentry kind="src" path="src/java"/>
  <classpathentry kind="src" path="src/resources"/>
  <classpathentry kind="src" path="src/gen-java"/>
  <classpathentry kind="src" path="conf" including="hotspot_compiler"/>
  <classpathentry kind="src" output="build/test/classes" path="test/unit"/>
  <classpathentry kind="src" output="build/test/classes" path="test/long"/>
  <classpathentry kind="src" output="build/test/classes" path="test/distributed"/>
  <classpathentry kind="src" output="build/test/classes" path="test/resources" />
  <classpathentry kind="src" path="tools/stress/src"/>
  <classpathentry kind="src" path="tools/fqltool/src"/>
  <classpathentry kind="src" output="build/test/stress-classes" path="tools/stress/test/unit" />
  <classpathentry kind="src" output="build/test/fqltool-classes" path="tools/fqltool/test/unit" />
  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
  <classpathentry kind="output" path="build/classes/eclipse"/>
  <classpathentry kind="lib" path="test/conf"/>
  <classpathentry kind="lib" path="${java.home}/../lib/tools.jar"/>
]]>
    </echo>
      <path id="eclipse-project-libs-path">
       <fileset dir="lib">
          <include name="**/*.jar" />
     </fileset>
      <fileset dir="build/lib/jars">
          <include name="**/*.jar" />
       </fileset>
     <fileset dir="build/test/lib/jars">
        <include name="**/*.jar" />
     </fileset>
      </path>
      <property name="eclipse-project-libs" refid="eclipse-project-libs-path"/>
       <script language="javascript">
        <classpath>
            <path refid="cassandra.classpath"/>
            <path refid="cassandra.classpath.test"/>
        </classpath>
        <![CDATA[
        var File = java.io.File;
          var FilenameUtils = Packages.org.apache.commons.io.FilenameUtils;
          jars = project.getProperty("eclipse-project-libs").split(project.getProperty("path.separator"));

          cp = "";
          for (i=0; i< jars.length; i++) {
             srcjar = FilenameUtils.getBaseName(jars[i]) + '-sources.jar';
           srcdir = FilenameUtils.concat(project.getProperty("build.test.dir"), 'sources');
             srcfile = new File(FilenameUtils.concat(srcdir, srcjar));

             cp += ' <classpathentry kind="lib" path="' + jars[i] + '"';
             if (srcfile.exists()) {
                cp += ' sourcepath="' + srcfile.getAbsolutePath() + '"';
             }
             cp += '/>\n';
          }

          cp += '</classpath>';

          echo = project.createTask("echo");
          echo.setMessage(cp);
          echo.setFile(new File(".classpath"));
          echo.setAppend(true);
          echo.perform();
      ]]> </script>
    <mkdir dir=".settings" />
  </target>

  <pathconvert property="eclipse.project.name">
    <path path="${basedir}" />
    <regexpmapper from="^.*/([^/]+)$$" to="\1" handledirsep="yes" />
  </pathconvert>

  <!-- Clean Eclipse project description files -->
  <target name="clean-eclipse-files">
    <delete file=".project" />
    <delete file=".classpath" />
    <delete dir=".settings" />
      <delete dir=".externalToolBuilders" />
      <delete dir="build/eclipse-classes" />
  </target>

  <!-- ECJ 4.6.1 in standalone mode does not work with JPMS, so we skip this target for Java 11 -->
  <target name="eclipse-warnings" depends="build, _assert_rat_output" description="Run eclipse compiler code analysis" if="java.version.8">
        <property name="ecj.log.dir" value="${build.dir}/ecj" />
        <property name="ecj.warnings.file" value="${ecj.log.dir}/eclipse_compiler_checks.txt"/>
        <mkdir  dir="${ecj.log.dir}" />

        <property name="ecj.properties" value="${basedir}/eclipse_compiler.properties" />

        <echo message="Running Eclipse Code Analysis.  Output logged to ${ecj.warnings.file}" />

    <java
        jar="${build.dir.lib}/jars/ecj-${ecj.version}.jar"
            fork="true"
        failonerror="true"
            maxmemory="512m">
            <arg value="-source"/>
        <arg value="${source.version}" />
        <arg value="-target"/>
        <arg value="${target.version}" />
        <arg value="-d" />
            <arg value="none" />
        <arg value="-proc:none" />
            <arg value="-log" />
            <arg value="${ecj.warnings.file}" />
            <arg value="-properties" />
            <arg value="${ecj.properties}" />
            <arg value="-cp" />
            <arg value="${toString:cassandra.classpath}" />
            <arg value="${build.src.java}" />
        </java>
  </target>


  <!-- Installs artifacts to local Maven repository -->
  <target name="mvn-install"
          depends="maven-declare-dependencies,jar,sources-jar,javadoc-jar"
          description="Installs the artifacts in the Maven Local Repository">

    <!-- the parent -->
    <install pomFile="${build.dir}/${final.name}-parent.pom"
             file="${build.dir}/${final.name}-parent.pom"
             packaging="pom"/>

    <!-- the cassandra-all jar -->
    <install pomFile="${build.dir}/${final.name}.pom"
             file="${build.dir}/${final.name}.jar"/>
    <install pomFile="${build.dir}/${final.name}.pom"
             file="${build.dir}/${final.name}-sources.jar"
             classifier="sources"/>
    <install pomFile="${build.dir}/${final.name}.pom"
             file="${build.dir}/${final.name}-javadoc.jar"
             classifier="javadoc"/>
  </target>

  <!-- Publish artifacts to remote Maven repository -->
  <target name="publish"
          depends="mvn-install,artifacts"
          description="Publishes the artifacts to the Maven repository">

    <!-- the parent -->
    <deploy pomFile="${build.dir}/${final.name}-parent.pom"
            file="${build.dir}/${final.name}-parent.pom"
            packaging="pom"/>

    <!-- the cassandra-all jar -->
    <deploy pomFile="${build.dir}/${final.name}.pom"
            file="${build.dir}/${final.name}.jar"/>
    <deploy pomFile="${build.dir}/${final.name}.pom"
            file="${build.dir}/${final.name}-sources.jar"
            classifier="sources"/>
    <deploy pomFile="${build.dir}/${final.name}.pom"
            file="${build.dir}/${final.name}-javadoc.jar"
            classifier="javadoc"/>

    <!-- the distribution -->
    <sign-dist file="${build.dir}/${final.name}-bin.tar.gz" />
    <sign-dist file="${build.dir}/${final.name}-src.tar.gz" />

  </target>

  <import file="${basedir}/.build/build-resolver.xml"/>
  <import file="${basedir}/.build/build-rat.xml"/>
  <import file="${basedir}/.build/build-owasp.xml"/>
</project>
