You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by th...@apache.org on 2020/09/14 16:38:18 UTC

[lucene-solr] branch reference_impl_gradle_updates created (now 2806475)

This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a change to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git.


      at 2806475  LUCENE-9474: Remove bad warning (we sometimes have non-existing directories in classpaths during compile). This warnings is not source-code related so shouldn't be enforced (Java 14)

This branch includes the following new commits:

     new 0edf0f3  LUCENE-9411: Fail complation on warnings, 9x gradle-only
     new 4a47c3c  LUCENE-9312: Allow builds against arbitrary JVMs (squashed jira/LUCENE-9312)
     new 17d664f  LUCENE-9465: 'beast' task from within gradle (#1757)
     new ece125a  LUCENE-9471: clean up task and global temporary junk files (workaround). (#1767)
     new ed27e86  LUCENE-9438: Eclipse IDE support with gradle build system (#1761)
     new c188e80  LUCENE-9474: Make the version number configurable from outside. This mainly allows Jenkins to set a different suffix than "SNAPSHOT"
     new 9a8b577  LUCENE-9474: Make external tools configurable like in ant through those sysprops: perl.exe, python3.exe, python2.exe
     new 969c8ec  LUCENE-9435: Clean up ant compatability remnants in Gradle build
     new 4f2ef00  LUCENE-9474: make externalTool a function and add a build-stopping message on Windows for snowball generator.
     new 72bf564  LUCENE-9491: Consolidate test options and improve support for dynamic… (#1807)
     new 015e92f  LUCENE-9435: revert Solr's packaging stuff for now.
     new 691aa6d  Move Solr-specific config.
     new 7f54fa2  LUCENE-9215: replace checkJavaDocs.py with doclet (#1802)
     new 17a3ba7  LUCENE-9497: Integerate Error Prone ( Static Analysis Tool ) during compilation (#1816)
     new 4c9931a  LUCENE-9518: Add sanity to gradle archiving tasks (predictable order, default permissions, fail on duplicates) (#1851)
     new cc5b672  LUCENE-9433: Remove Ant support from trunk
     new 131a564  LUCENE-9475: Enhance the Gradle build as necessary after removing Ant support
     new 568b006  LUCENE-9475: Enhance the Gradle build as necessary after removing Ant support, some minor text changes to solr/README.md and help.gradle
     new 2d32436  LUCENE-9441: Fix ant-specific Javadoc links in accordance with Gradle build
     new 0adba5e  LUCENE-9490: skip checkMissingDocsDefault on runtime Java > 14.
     new 4a78c20  LUCENE-9490: Disable both tasks in :lucene:core on Java 15+
     new 843e61d  master is on java 11!
     new 92fb5e2  LUCENE-9475: Switch validateSourcePatterns away from Ant legacy (#1806)
     new 17770b3  LUCENE-9438: moved eclipse template files under corresponding gradle's script.
     new ff33a63  Cleanup remaining scripts to use script-relative resource location.
     new a3665fe  LUCENE-9492: Fix beasting to accept also task names in form ":project:beast"; fix bug with default value rejected by Integer.parseInt (#1808)
     new b59438e  LUCENE-9438: Add resources to the Eclipse classpath.
     new 97188fb  Remove the explicit dependency to "check", as fobiddenapis installs it automatically (especially for all source sets; if we want this explicit dependency, it should depend on 'forbiddenApis' not each task). In addition precommit, also adds it.
     new afb3379  LUCENE-9505: add dummy outputs. (#1829)
     new 9f27041  LUCENE-9475: remove obsolete ant-only jar sha's from Solr.
     new e952c4f  LUCENE-9506: Gradle: split validateSourcePatterns into per-project an… (#1830)
     new 9b83be5  LUCENE-9512: Move LockFactory stress test to be a unit/integration test (#1842)
     new 8e95b90  LUCENE-9517: Don't subclass Deflater and instead create a patch for setDictionary() using a functional interface (#1850)
     new 7a8da0a  SOLR-14836: Exclude README.committers.txt from distribution
     new 86c633d  SOLR-14789: Absorb the docker-solr repo. (#1769)
     new d2f7780  SOLR-14847: Create Solr Server TGZ (#1844)
     new 5083e02  LUCENE-9411: Fail complation on warnings, 9x gradle-only. Explicitly list warnings to check for
     new df4857d  Update versions.lock after cherry-picks
     new 2806475  LUCENE-9474: Remove bad warning (we sometimes have non-existing directories in classpaths during compile). This warnings is not source-code related so shouldn't be enforced (Java 14)

The 39 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[lucene-solr] 33/39: LUCENE-9517: Don't subclass Deflater and instead create a patch for setDictionary() using a functional interface (#1850)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 8e95b900130e0d9658d0121a972bba1c1ec0dde5
Author: Uwe Schindler <us...@apache.org>
AuthorDate: Thu Sep 10 11:12:59 2020 +0200

    LUCENE-9517: Don't subclass Deflater and instead create a patch for setDictionary() using a functional interface (#1850)
---
 gradle/validation/forbidden-apis/defaults.all.txt  |   4 +
 .../codecs/lucene87/BugfixDeflater_JDK8252739.java | 110 ++++++++++
 .../DeflateWithPresetDictCompressionMode.java      | 226 +++++++++++++++++++++
 3 files changed, 340 insertions(+)

diff --git a/gradle/validation/forbidden-apis/defaults.all.txt b/gradle/validation/forbidden-apis/defaults.all.txt
index 6ff080b..6c6e029 100644
--- a/gradle/validation/forbidden-apis/defaults.all.txt
+++ b/gradle/validation/forbidden-apis/defaults.all.txt
@@ -62,3 +62,7 @@ java.lang.Double#<init>(java.lang.String)
 @defaultMessage Java deserialization is unsafe when the data is untrusted. The java developer is powerless: no checks or casts help, exploitation can happen in places such as clinit or finalize!
 java.io.ObjectInputStream
 java.io.ObjectOutputStream
+
+@defaultMessage Don't set a dictionary on a Deflater using a method that takes an offset or ByteBuffer (JDK-8252739)
+java.util.zip.Deflater#setDictionary(byte[],int,int)
+java.util.zip.Deflater#setDictionary(java.nio.ByteBuffer)
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene87/BugfixDeflater_JDK8252739.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene87/BugfixDeflater_JDK8252739.java
new file mode 100644
index 0000000..582715e
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene87/BugfixDeflater_JDK8252739.java
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.codecs.lucene87;
+
+import java.util.Arrays;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+
+import org.apache.lucene.util.SuppressForbidden;
+
+/**
+ * This class is a workaround for JDK bug
+ * <a href="https://bugs.openjdk.java.net/browse/JDK-8252739">JDK-8252739</a>.
+ */
+@FunctionalInterface
+interface BugfixDeflater_JDK8252739 {
+  
+  public static final boolean IS_BUGGY_JDK = detectBuggyJDK();
+
+  /**
+   * Creates a bugfix for {@link Deflater} instances, which works around JDK-8252739.
+   * <p>
+   * Use this whenever you intend to call {@link Deflater#setDictionary(byte[], int, int)}
+   * on a {@code Deflater}.
+   * */
+  @SuppressForbidden(reason = "Works around bug, so it must call forbidden method")
+  public static BugfixDeflater_JDK8252739 createBugfix(Deflater deflater, int dictLength) {
+    if (dictLength < 0) {
+      throw new IllegalArgumentException("dictLength must be >= 0");
+    }
+    if (IS_BUGGY_JDK) {
+      final byte[] dictBytesScratch = new byte[dictLength];
+      return (dictBytes, off, len) -> {
+        if (off > 0) {
+          System.arraycopy(dictBytes, off, dictBytesScratch, 0, len);
+          deflater.setDictionary(dictBytesScratch, 0, len);
+        } else {
+          deflater.setDictionary(dictBytes, off, len);
+        }
+      };
+    } else {
+      return deflater::setDictionary;
+    }
+  }
+  
+  /** Call this method as a workaround */
+  void setDictionary(byte[] dictBytes, int off, int len);
+  
+  @SuppressForbidden(reason = "Detector for the bug, so it must call buggy method")
+  private static boolean detectBuggyJDK() {
+    final byte[] testData = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
+    final byte[] compressed = new byte[32]; // way enough space
+    final Deflater deflater = new Deflater(6, true);
+    int compressedSize;
+    try {
+      deflater.reset();
+      deflater.setDictionary(testData, 4, 4);
+      deflater.setInput(testData);
+      deflater.finish();
+      compressedSize = deflater.deflate(compressed, 0, compressed.length, Deflater.FULL_FLUSH);
+    } finally {
+      deflater.end();
+    }
+    
+    // in nowrap mode we need extra 0-byte as padding, add explicit:
+    compressed[compressedSize] = 0;
+    compressedSize++;
+    
+    final Inflater inflater = new Inflater(true);
+    final byte[] restored = new byte[testData.length];
+    try {
+      inflater.reset();
+      inflater.setDictionary(testData, 4, 4);
+      inflater.setInput(compressed, 0, compressedSize);
+      final int restoredLength = inflater.inflate(restored);
+      if (restoredLength != testData.length) {
+        return true;
+      }
+    } catch (DataFormatException e) {
+      return true;
+    } catch(RuntimeException e) {
+      return true;
+    } finally {
+      inflater.end();
+    }
+
+    if (Arrays.equals(testData, restored) == false) {
+      return true;
+    }
+    
+    // all fine
+    return false;
+  }
+  
+}
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene87/DeflateWithPresetDictCompressionMode.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene87/DeflateWithPresetDictCompressionMode.java
new file mode 100644
index 0000000..4269740
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene87/DeflateWithPresetDictCompressionMode.java
@@ -0,0 +1,226 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.codecs.lucene87;
+
+import java.io.IOException;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+
+import org.apache.lucene.codecs.compressing.CompressionMode;
+import org.apache.lucene.codecs.compressing.Compressor;
+import org.apache.lucene.codecs.compressing.Decompressor;
+import org.apache.lucene.index.CorruptIndexException;
+import org.apache.lucene.store.DataInput;
+import org.apache.lucene.store.DataOutput;
+import org.apache.lucene.util.ArrayUtil;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ * A compression mode that trades speed for compression ratio. Although
+ * compression and decompression might be slow, this compression mode should
+ * provide a good compression ratio. This mode might be interesting if/when
+ * your index size is much bigger than your OS cache.
+ * @lucene.internal
+ */
+public final class DeflateWithPresetDictCompressionMode extends CompressionMode {
+
+  private final int dictLength, subBlockLength;
+
+  /** Sole constructor. */
+  public DeflateWithPresetDictCompressionMode(int dictLength, int subBlockLength) {
+    this.dictLength = dictLength;
+    this.subBlockLength = subBlockLength;
+  }
+
+  @Override
+  public Compressor newCompressor() {
+    // notes:
+    // 3 is the highest level that doesn't have lazy match evaluation
+    // 6 is the default, higher than that is just a waste of cpu
+    return new DeflateWithPresetDictCompressor(6, dictLength, subBlockLength);
+  }
+
+  @Override
+  public Decompressor newDecompressor() {
+    return new DeflateWithPresetDictDecompressor();
+  }
+
+  @Override
+  public String toString() {
+    return "BEST_COMPRESSION";
+  }
+
+  private static final class DeflateWithPresetDictDecompressor extends Decompressor {
+
+    byte[] compressed;
+
+    DeflateWithPresetDictDecompressor() {
+      compressed = new byte[0];
+    }
+
+    private void doDecompress(DataInput in, Inflater decompressor, BytesRef bytes) throws IOException {
+      final int compressedLength = in.readVInt();
+      if (compressedLength == 0) {
+        return;
+      }
+      // pad with extra "dummy byte": see javadocs for using Inflater(true)
+      // we do it for compliance, but it's unnecessary for years in zlib.
+      final int paddedLength = compressedLength + 1;
+      compressed = ArrayUtil.grow(compressed, paddedLength);
+      in.readBytes(compressed, 0, compressedLength);
+      compressed[compressedLength] = 0; // explicitly set dummy byte to 0
+
+      // extra "dummy byte"
+      decompressor.setInput(compressed, 0, paddedLength);
+      try {
+        bytes.length += decompressor.inflate(bytes.bytes, bytes.length, bytes.bytes.length - bytes.length);
+      } catch (DataFormatException e) {
+        throw new IOException(e);
+      }
+      if (decompressor.finished() == false) {
+        throw new CorruptIndexException("Invalid decoder state: needsInput=" + decompressor.needsInput()
+        + ", needsDict=" + decompressor.needsDictionary(), in);
+      }
+    }
+
+    @Override
+    public void decompress(DataInput in, int originalLength, int offset, int length, BytesRef bytes) throws IOException {
+      assert offset + length <= originalLength;
+      if (length == 0) {
+        bytes.length = 0;
+        return;
+      }
+      final int dictLength = in.readVInt();
+      final int blockLength = in.readVInt();
+      bytes.bytes = ArrayUtil.grow(bytes.bytes, dictLength);
+      bytes.offset = bytes.length = 0;
+
+      final Inflater decompressor = new Inflater(true);
+      try {
+        // Read the dictionary
+        doDecompress(in, decompressor, bytes);
+        if (dictLength != bytes.length) {
+          throw new CorruptIndexException("Unexpected dict length", in);
+        }
+
+        int offsetInBlock = dictLength;
+        int offsetInBytesRef = offset;
+
+        // Skip unneeded blocks
+        while (offsetInBlock + blockLength < offset) {
+          final int compressedLength = in.readVInt();
+          in.skipBytes(compressedLength);
+          offsetInBlock += blockLength;
+          offsetInBytesRef -= blockLength;
+        }
+
+        // Read blocks that intersect with the interval we need
+        while (offsetInBlock < offset + length) {
+          bytes.bytes = ArrayUtil.grow(bytes.bytes, bytes.length + blockLength);
+          decompressor.reset();
+          decompressor.setDictionary(bytes.bytes, 0, dictLength);
+          doDecompress(in, decompressor, bytes);
+          offsetInBlock += blockLength;
+        }
+
+        bytes.offset = offsetInBytesRef;
+        bytes.length = length;
+        assert bytes.isValid();
+      } finally {
+        decompressor.end();
+      }
+    }
+
+    @Override
+    public Decompressor clone() {
+      return new DeflateWithPresetDictDecompressor();
+    }
+
+  }
+
+  private static class DeflateWithPresetDictCompressor extends Compressor {
+
+    private final int dictLength, blockLength;
+    final Deflater compressor;
+    final BugfixDeflater_JDK8252739 deflaterBugfix;
+    byte[] compressed;
+    boolean closed;
+
+    DeflateWithPresetDictCompressor(int level, int dictLength, int blockLength) {
+      compressor = new Deflater(level, true);
+      deflaterBugfix = BugfixDeflater_JDK8252739.createBugfix(compressor, dictLength);
+      compressed = new byte[64];
+      this.dictLength = dictLength;
+      this.blockLength = blockLength;
+    }
+
+    private void doCompress(byte[] bytes, int off, int len, DataOutput out) throws IOException {
+      if (len == 0) {
+        out.writeVInt(0);
+        return;
+      }
+      compressor.setInput(bytes, off, len);
+      compressor.finish();
+      if (compressor.needsInput()) {
+        throw new IllegalStateException();
+      }
+
+      int totalCount = 0;
+      for (;;) {
+        final int count = compressor.deflate(compressed, totalCount, compressed.length - totalCount);
+        totalCount += count;
+        assert totalCount <= compressed.length;
+        if (compressor.finished()) {
+          break;
+        } else {
+          compressed = ArrayUtil.grow(compressed);
+        }
+      }
+
+      out.writeVInt(totalCount);
+      out.writeBytes(compressed, totalCount);
+    }
+
+    @Override
+    public void compress(byte[] bytes, int off, int len, DataOutput out) throws IOException {
+      final int dictLength = Math.min(this.dictLength, len);
+      out.writeVInt(dictLength);
+      out.writeVInt(blockLength);
+      final int end = off + len;
+
+      // Compress the dictionary first
+      compressor.reset();
+      doCompress(bytes, off, dictLength, out);
+
+      // And then sub blocks
+      for (int start = off + dictLength; start < end; start += blockLength) {
+        compressor.reset();
+        deflaterBugfix.setDictionary(bytes, off, dictLength);
+        doCompress(bytes, start, Math.min(blockLength, off + len - start), out);
+      }
+    }
+
+    @Override
+    public void close() throws IOException {
+      if (closed == false) {
+        compressor.end();
+        closed = true;
+      }
+    }
+  }
+}


[lucene-solr] 18/39: LUCENE-9475: Enhance the Gradle build as necessary after removing Ant support, some minor text changes to solr/README.md and help.gradle

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 568b0061a8310dc91bf85f3fe9a6b3d194ee416a
Author: Erick Erickson <Er...@gmail.com>
AuthorDate: Sun Sep 6 17:15:56 2020 -0400

    LUCENE-9475: Enhance the Gradle build as necessary after removing Ant support, some minor text changes to solr/README.md and help.gradle
---
 gradle/help.gradle |  3 +++
 solr/README.md     | 31 +++++++++++++++++++------------
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/gradle/help.gradle b/gradle/help.gradle
index 51435e1..e03d724 100644
--- a/gradle/help.gradle
+++ b/gradle/help.gradle
@@ -46,10 +46,13 @@ configure(rootProject) {
       println ""
       println "This is an experimental Lucene/Solr gradle build. See some"
       println "guidelines, ant-equivalent commands etc. under help/*; or type:"
+      println ""
       helpFiles.each { section, path, sectionInfo ->
         println String.format(Locale.ROOT,
             "  gradlew :help%-16s # %s", section, sectionInfo)
       }
+      println ""
+      println "For the impatient, build the project with 'gradlew assemble' or 'gradlew dev' "
     }
   }
 
diff --git a/solr/README.md b/solr/README.md
index 176e007..2401e2b 100644
--- a/solr/README.md
+++ b/solr/README.md
@@ -29,7 +29,9 @@ https://lucene.apache.org/solr
 Getting Started
 ---------------
 
-To start Solr for the first time after installation, simply do:
+All the following commands are entered from the "solr" directory which should be just below the install directory
+
+To start Solr for the first time after installation, simply enter:
 
 ```
   bin/solr start
@@ -38,20 +40,20 @@ To start Solr for the first time after installation, simply do:
 This will launch a standalone Solr server in the background of your shell,
 listening on port 8983. Alternatively, you can launch Solr in "cloud" mode,
 which allows you to scale out using sharding and replication. To launch Solr
-in cloud mode, do:
+in cloud mode, enter:
 
 ```
   bin/solr start -cloud
 ```
 
-To see all available options for starting Solr, please do:
+To see all available options for starting Solr, please enter:
 
 ```
   bin/solr start -help
 ```
 
 After starting Solr, create either a core or collection depending on whether
-Solr is running in standalone (core) or SolrCloud mode (collection) by doing:
+Solr is running in standalone (core) or SolrCloud mode (collection) by entering:
 
 ```
   bin/solr create -c <name>
@@ -59,7 +61,7 @@ Solr is running in standalone (core) or SolrCloud mode (collection) by doing:
 
 This will create a collection that uses a data-driven schema which tries to guess
 the correct field type when you add documents to the index. To see all available
-options for creating a new collection, execute:
+options for creating a new collection, enter:
 
 ```
   bin/solr create -help
@@ -84,21 +86,20 @@ where more than one Solr is running on the machine.
 Solr Examples
 ---------------
 
-Solr includes a few examples to help you get started. To run a specific example, do:
+Solr includes a few examples to help you get started. To run a specific example, enter:
 
 ```
   bin/solr -e <EXAMPLE> where <EXAMPLE> is one of:
 
     cloud        : SolrCloud example
-    dih          : Data Import Handler (rdbms, mail, atom, tika)
     schemaless   : Schema-less example (schema is inferred from data during indexing)
     techproducts : Kitchen sink example providing comprehensive examples of Solr features
 ```
 
-For instance, if you want to run the Solr Data Import Handler example, do:
+For instance, if you want to run the SolrCloud example, enter:
 
 ```
-  bin/solr -e dih
+  bin/solr -e cloud
 ```
 
 Indexing Documents
@@ -142,8 +143,7 @@ server/
 
 example/
   Contains example documents and an alternative Solr home
-  directory containing examples of how to use the Data Import Handler,
-  see example/example-DIH/README.md for more information.
+  directory containing various examples.
 
 dist/solr-<component>-XX.jar
   The Apache Solr libraries.  To compile Apache Solr Plugins,
@@ -177,8 +177,15 @@ Instructions for Building Apache Solr from Source
    cd to "./solr/packaging/build/solr-9.0.0-SNAPSHOT" and run the bin/solr script
    to start Solr.
    
-   NOTE: `gradlew` is the "Gradle Wrapper" and will automaticaly download and
+   NOTE: `gradlew` is the "Gradle Wrapper" and will automatically download and
    start using the correct version of Gradle.
+   
+   NOTE: `./gradlew help` will print a list of high-level tasks. There are also a 
+   number of plain-text files in <source folder root>/help.
+   
+   NOTE: This CWiki page describes getting/building/testing Solr
+   in more detail:
+   `https://cwiki.apache.org/confluence/display/solr/HowToContribute` 
 
 Export control
 -------------------------------------------------


[lucene-solr] 16/39: LUCENE-9433: Remove Ant support from trunk

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit cc5b672e5080e70de55af263a15472c614f4d424
Author: Erick Erickson <Er...@gmail.com>
AuthorDate: Fri Aug 28 09:31:16 2020 -0400

    LUCENE-9433: Remove Ant support from trunk
---
 .github/PULL_REQUEST_TEMPLATE.md                   |   2 +-
 README.md                                          |  72 +-
 build.xml                                          | 697 ------------------
 dev-tools/idea/.idea/ant.xml                       |  57 --
 dev-tools/idea/.idea/libraries/Ivy.xml             |   9 -
 dev-tools/maven/README.maven                       | 159 ----
 .../maven/lucene/analysis/common/pom.xml.template  |  86 ---
 .../maven/lucene/analysis/icu/pom.xml.template     |  76 --
 .../lucene/analysis/kuromoji/pom.xml.template      |  75 --
 .../lucene/analysis/morfologik/pom.xml.template    |  78 --
 .../maven/lucene/analysis/nori/pom.xml.template    |  75 --
 .../maven/lucene/analysis/opennlp/pom.xml.template |  78 --
 .../lucene/analysis/phonetic/pom.xml.template      |  75 --
 dev-tools/maven/lucene/analysis/pom.xml.template   |  55 --
 .../maven/lucene/analysis/smartcn/pom.xml.template |  73 --
 .../maven/lucene/analysis/stempel/pom.xml.template |  73 --
 .../maven/lucene/backward-codecs/pom.xml.template  |  88 ---
 dev-tools/maven/lucene/benchmark/pom.xml.template  |  86 ---
 .../maven/lucene/classification/pom.xml.template   |  68 --
 dev-tools/maven/lucene/codecs/pom.xml.template     |  48 --
 .../maven/lucene/codecs/src/java/pom.xml.template  |  85 ---
 .../maven/lucene/codecs/src/test/pom.xml.template  |  84 ---
 dev-tools/maven/lucene/core/pom.xml.template       |  48 --
 .../maven/lucene/core/src/java/pom.xml.template    |  79 --
 .../maven/lucene/core/src/test/pom.xml.template    |  84 ---
 dev-tools/maven/lucene/demo/pom.xml.template       |  85 ---
 .../maven/lucene/expressions/pom.xml.template      |  62 --
 dev-tools/maven/lucene/facet/pom.xml.template      |  75 --
 dev-tools/maven/lucene/grouping/pom.xml.template   |  68 --
 .../maven/lucene/highlighter/pom.xml.template      |  70 --
 dev-tools/maven/lucene/join/pom.xml.template       |  68 --
 dev-tools/maven/lucene/memory/pom.xml.template     |  70 --
 dev-tools/maven/lucene/misc/pom.xml.template       |  68 --
 dev-tools/maven/lucene/monitor/pom.xml.template    |  70 --
 dev-tools/maven/lucene/pom.xml.template            | 127 ----
 dev-tools/maven/lucene/queries/pom.xml.template    |  68 --
 .../maven/lucene/queryparser/pom.xml.template      |  86 ---
 dev-tools/maven/lucene/replicator/pom.xml.template |  74 --
 dev-tools/maven/lucene/sandbox/pom.xml.template    |  73 --
 .../maven/lucene/spatial-extras/pom.xml.template   |  69 --
 dev-tools/maven/lucene/spatial3d/pom.xml.template  |  70 --
 dev-tools/maven/lucene/suggest/pom.xml.template    |  73 --
 .../maven/lucene/test-framework/pom.xml.template   | 109 ---
 .../solr/contrib/analysis-extras/pom.xml.template  |  85 ---
 .../maven/solr/contrib/analytics/pom.xml.template  |  80 --
 .../maven/solr/contrib/clustering/pom.xml.template |  78 --
 .../dataimporthandler-extras/pom.xml.template      |  85 ---
 .../contrib/dataimporthandler/pom.xml.template     |  91 ---
 .../maven/solr/contrib/extraction/pom.xml.template |  81 --
 .../jaegertracer-configurator/pom.xml.template     |  80 --
 .../maven/solr/contrib/langid/pom.xml.template     |  87 ---
 dev-tools/maven/solr/contrib/ltr/pom.xml.template  |  80 --
 dev-tools/maven/solr/contrib/pom.xml.template      |  57 --
 .../contrib/prometheus-exporter/pom.xml.template   |  80 --
 .../maven/solr/contrib/velocity/pom.xml.template   |  89 ---
 dev-tools/maven/solr/core/pom.xml.template         |  48 --
 .../maven/solr/core/src/java/pom.xml.template      |  84 ---
 .../maven/solr/core/src/test/pom.xml.template      | 155 ----
 dev-tools/maven/solr/maven.testlogging.properties  |   2 -
 dev-tools/maven/solr/pom.xml.template              | 186 -----
 dev-tools/maven/solr/solrj/pom.xml.template        |  48 --
 .../maven/solr/solrj/src/java/pom.xml.template     |  78 --
 .../maven/solr/solrj/src/test/pom.xml.template     | 122 ----
 .../maven/solr/test-framework/pom.xml.template     |  95 ---
 lucene/BUILD.md                                    |  81 +-
 lucene/CHANGES.txt                                 |   5 -
 lucene/analysis/analysis-module-build.xml          |  44 --
 lucene/analysis/build.xml                          | 172 -----
 lucene/analysis/common/build.xml                   | 125 ----
 lucene/analysis/common/ivy.xml                     |  21 -
 lucene/analysis/icu/build.xml                      | 118 ---
 lucene/analysis/icu/ivy.xml                        |  28 -
 lucene/analysis/kuromoji/build.xml                 |  98 ---
 lucene/analysis/kuromoji/ivy.xml                   |  37 -
 lucene/analysis/morfologik/build.xml               |  40 -
 lucene/analysis/morfologik/ivy.xml                 |  31 -
 lucene/analysis/nori/build.xml                     |  84 ---
 lucene/analysis/nori/ivy.xml                       |  33 -
 lucene/analysis/opennlp/build.xml                  | 118 ---
 lucene/analysis/opennlp/ivy.xml                    |  28 -
 lucene/analysis/phonetic/build.xml                 |  35 -
 lucene/analysis/phonetic/ivy.xml                   |  28 -
 lucene/analysis/smartcn/build.xml                  |  34 -
 lucene/analysis/smartcn/ivy.xml                    |  21 -
 lucene/analysis/stempel/build.xml                  |  34 -
 lucene/analysis/stempel/ivy.xml                    |  21 -
 lucene/backward-codecs/build.xml                   |  26 -
 lucene/backward-codecs/ivy.xml                     |  21 -
 lucene/benchmark/build.xml                         | 289 --------
 lucene/benchmark/ivy.xml                           |  32 -
 lucene/build.xml                                   | 586 ---------------
 lucene/classification/build.xml                    |  55 --
 lucene/classification/ivy.xml                      |  21 -
 lucene/codecs/build.xml                            |  28 -
 lucene/codecs/ivy.xml                              |  21 -
 lucene/core/build.xml                              | 235 ------
 lucene/core/ivy.xml                                |  21 -
 lucene/default-nested-ivy-settings.xml             |  56 --
 lucene/demo/build.xml                              |  61 --
 lucene/demo/ivy.xml                                |  21 -
 lucene/expressions/build.xml                       | 120 ---
 lucene/expressions/ivy.xml                         |  30 -
 lucene/facet/build.xml                             |  47 --
 lucene/facet/ivy.xml                               |  27 -
 lucene/grouping/build.xml                          |  49 --
 lucene/grouping/ivy.xml                            |  21 -
 lucene/highlighter/ivy.xml                         |  21 -
 lucene/ivy-ignore-conflicts.properties             |  14 -
 lucene/join/build.xml                              |  27 -
 lucene/join/ivy.xml                                |  21 -
 lucene/licenses/ant-1.8.2.jar.sha1                 |   1 -
 lucene/licenses/ant-LICENSE-ASL.txt                | 272 -------
 lucene/licenses/ant-NOTICE.txt                     |  26 -
 lucene/licenses/ivy-2.4.0.jar.sha1                 |   1 -
 lucene/licenses/ivy-LICENSE-ASL.txt                | 258 -------
 lucene/licenses/ivy-NOTICE.txt                     |  16 -
 lucene/luke/build.xml                              |  82 ---
 lucene/luke/ivy.xml                                |  34 -
 lucene/memory/build.xml                            |  34 -
 lucene/memory/ivy.xml                              |  21 -
 lucene/misc/build.xml                              |  52 --
 lucene/misc/ivy.xml                                |  21 -
 lucene/module-build.xml                            | 721 ------------------
 lucene/monitor/build.xml                           |  53 --
 lucene/monitor/ivy.xml                             |  21 -
 lucene/queries/build.xml                           |  32 -
 lucene/queries/ivy.xml                             |  21 -
 lucene/queryparser/build.xml                       | 178 -----
 lucene/queryparser/ivy.xml                         |  21 -
 lucene/queryparser/xmldtddocbuild.xml              |  53 --
 lucene/replicator/build.xml                        |  53 --
 lucene/replicator/ivy.xml                          |  47 --
 lucene/sandbox/build.xml                           |  26 -
 lucene/sandbox/ivy.xml                             |  21 -
 lucene/spatial-extras/build.xml                    |  62 --
 lucene/spatial-extras/ivy.xml                      |  40 -
 lucene/spatial3d/build.xml                         |  30 -
 lucene/spatial3d/ivy.xml                           |  21 -
 lucene/suggest/build.xml                           |  47 --
 lucene/suggest/ivy.xml                             |  21 -
 lucene/test-framework/build.xml                    |  82 ---
 lucene/top-level-ivy-settings.xml                  |  24 -
 solr/CHANGES.txt                                   | 301 +++++++-
 solr/README.md                                     |  28 +-
 solr/build.xml                                     | 813 ---------------------
 solr/common-build.xml                              | 551 --------------
 solr/contrib/analysis-extras/build.xml             |  92 ---
 solr/contrib/analysis-extras/ivy.xml               |  41 --
 solr/contrib/analytics/build.xml                   |  28 -
 solr/contrib/analytics/ivy.xml                     |  29 -
 solr/contrib/clustering/build.xml                  |  28 -
 solr/contrib/clustering/ivy.xml                    |  41 --
 solr/contrib/contrib-build.xml                     |  57 --
 solr/contrib/dataimporthandler-extras/build.xml    |  96 ---
 solr/contrib/dataimporthandler-extras/ivy.xml      |  40 -
 solr/contrib/dataimporthandler/build.xml           |  32 -
 solr/contrib/extraction/build.xml                  |  28 -
 solr/contrib/extraction/ivy.xml                    |  80 --
 solr/contrib/jaegertracer-configurator/build.xml   |  34 -
 solr/contrib/jaegertracer-configurator/ivy.xml     |  32 -
 solr/contrib/langid/build.xml                      | 102 ---
 solr/contrib/langid/ivy.xml                        |  32 -
 solr/contrib/ltr/build.xml                         |  35 -
 solr/contrib/ltr/ivy.xml                           |  33 -
 solr/contrib/prometheus-exporter/build.xml         |  64 --
 solr/contrib/prometheus-exporter/ivy.xml           |  41 --
 solr/contrib/velocity/build.xml                    |  28 -
 solr/contrib/velocity/ivy.xml                      |  36 -
 solr/core/build.xml                                | 131 ----
 solr/example/example-DIH/build.xml                 |  42 --
 solr/example/example-DIH/ivy.xml                   |  29 -
 solr/licenses/ant-1.8.2.jar.sha1                   |   1 -
 solr/licenses/ant-LICENSE-ASL.txt                  | 272 -------
 solr/licenses/ant-NOTICE.txt                       |  26 -
 solr/licenses/asciidoctor-ant-1.6.2.jar.sha1       |   1 -
 solr/licenses/asciidoctor-ant-LICENSE-ASL.txt      | 202 -----
 solr/licenses/asciidoctor-ant-NOTICE.txt           |   5 -
 solr/licenses/junit4-ant-2.7.6.jar.sha1            |   1 -
 solr/licenses/junit4-ant-LICENSE-ASL.txt           | 202 -----
 solr/licenses/junit4-ant-NOTICE.txt                |  12 -
 solr/server/build.xml                              |  54 --
 solr/server/ivy.xml                                |  74 --
 solr/solr-ref-guide/README.adoc                    |  20 +-
 solr/solr-ref-guide/build.gradle                   |   2 -
 solr/solr-ref-guide/build.xml                      | 305 --------
 solr/solr-ref-guide/ivy.xml                        |  35 -
 .../src/meta-docs/asciidoc-syntax.adoc             |   2 +-
 solr/solr-ref-guide/src/meta-docs/jekyll.adoc      |   6 +-
 solr/solr-ref-guide/src/meta-docs/publish.adoc     |   4 +-
 .../tools/CustomizedAsciidoctorAntTask.java        |  34 -
 solr/solr-ref-guide/tools/asciidoctor-antlib.xml   |  22 -
 solr/solrj/build.xml                               |  88 ---
 solr/test-framework/build.xml                      | 121 ---
 193 files changed, 373 insertions(+), 15104 deletions(-)

diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 9f2f786..b08a1d8 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -38,6 +38,6 @@ Please review the following and check all that apply:
 - [ ] I have created a Jira issue and added the issue ID to my pull request title.
 - [ ] I have given Solr maintainers [access](https://help.github.com/en/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork) to contribute to my PR branch. (optional but recommended)
 - [ ] I have developed this patch against the `master` branch.
-- [ ] I have run `ant precommit` and the appropriate test suite.
+- [ ] I have run `./gradlew check`.
 - [ ] I have added tests for my changes.
 - [ ] I have added documentation for the [Ref Guide](https://github.com/apache/lucene-solr/tree/master/solr/solr-ref-guide) (for Solr changes only).
diff --git a/README.md b/README.md
index 5fd3581..544992b 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@
 Apache Lucene is a high-performance, full featured text search engine library
 written in Java.
 
-Apache Solr is an enterprise search platform written using Apache Lucene.
+Apache Solr is an enterprise search platform written in Java and using Apache Lucene.
 Major features include full-text search, index replication and sharding, and
 result faceting and highlighting.
 
@@ -40,48 +40,30 @@ comprehensive documentation, visit:
 
 (You do not need to do this if you downloaded a pre-built package)
 
-### Building with Ant
-
-Lucene and Solr are built using [Apache Ant](http://ant.apache.org/).  To build
-Lucene and Solr, run:
-
-`ant compile`
-
-If you see an error about Ivy missing while invoking Ant (e.g., `.ant/lib does
-not exist`), run `ant ivy-bootstrap` and retry.
-
-Sometimes you may face issues with Ivy (e.g., an incompletely downloaded artifact).
-Cleaning up the Ivy cache and retrying is a workaround for most of such issues: 
-
-`rm -rf ~/.ivy2/cache`
-
-The Solr server can then be packaged and prepared for startup by running the
-following command from the `solr/` directory:
-
-`ant server`
 
 ### Building with Gradle
 
-There is ongoing work (see [LUCENE-9077](https://issues.apache.org/jira/browse/LUCENE-9077))
-to switch the legacy ant-based build system to [gradle](https://gradle.org/).
-Please give it a try!
-
-At the moment of writing, the gradle build requires precisely Java 11 
-(it may or may not work with newer Java versions).
+As of 9.0, Lucene/Solr uses [Gradle](https://gradle.org/) as the build
+system. Ant build support has been removed.
 
 To build Lucene and Solr, run (`./` can be omitted on Windows):
 
 `./gradlew assemble`
 
-The command above also packages a full distribution of Solr server; the 
+
+The command above packages a full distribution of Solr server; the 
 package can be located at:
 
 `solr/packaging/build/solr-*`
 
 Note that the gradle build does not create or copy binaries throughout the
-source repository (like ant build does) so you need to switch to the
-packaging output folder above; the rest of the instructions below remain
-identical.  
+source repository so you need to switch to the packaging output folder above;
+the rest of the instructions below remain identical. The packaging directory 
+is rewritten on each build. 
+
+For development, especially when you have created test indexes etc, use
+the `./gradlew dev` task which will copy binaries to `./solr/packaging/build/dev`
+but _only_ overwrite the binaries which will preserve your test setup.
 
 ## Running Solr
 
@@ -104,16 +86,6 @@ Common options are described in some detail in solr/README.txt.  For an
 exhaustive treatment of options, run `bin/solr start -h` from the `solr/`
 directory.
 
-## Development/IDEs
-
-Ant can be used to generate project files compatible with most common IDEs.
-Run the ant command corresponding to your IDE of choice before attempting to
-import Lucene/Solr.
-
-- *Eclipse* - `ant eclipse` (See [this](https://cwiki.apache.org/confluence/display/solr/HowToConfigureEclipse) for details)
-- *IntelliJ* - `ant idea` (See [this](https://cwiki.apache.org/confluence/display/lucene/HowtoConfigureIntelliJ) for details)
-- *Netbeans* - `ant netbeans` (See [this](https://cwiki.apache.org/confluence/display/lucene/HowtoConfigureNetbeans) for details)
-
 ### Gradle build and IDE support
 
 - *IntelliJ* - IntelliJ idea can import the project out of the box. 
@@ -121,23 +93,17 @@ import Lucene/Solr.
 - *Eclipse*  - Not tested.
 - *Netbeans* - Not tested.
 
-## Running Tests
-
-The standard test suite can be run with the command:
-
-`ant test`
-
-Like Solr itself, the test-running can be customized or tailored in a number or
-ways.  For an exhaustive discussion of the options available, run:
-
-`ant test-help`
 
 ### Gradle build and tests
 
-Run the following command to display an extensive help for running
-tests with gradle:
+`./gradlew assemble` will build a runnable Solr as noted above.
+
+`./gradlew check` will assemble Lucene/Solr and run all validation
+  tasks unit tests.
 
-`./gradlew helpTests`
+`./gradlew help` will print a list of help commands for high-level tasks. One
+  of these is `helpAnt` that shows the gradle tasks corresponding to ant
+  targets you may be familiar with.
 
 ## Contributing
 
diff --git a/build.xml b/build.xml
deleted file mode 100755
index a1e8ccb..0000000
--- a/build.xml
+++ /dev/null
@@ -1,697 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="lucene-solr" default="-projecthelp" basedir=".">
-  <import file="lucene/common-build.xml"/>
-
-  <property name="jgit-version" value="5.3.0.201903130848-r"/>
-  
-  <property name="tests.heap-dump-dir" location="heapdumps"/>
-  
-  <property name="maven-build-dir" value="maven-build"/>
-  <property name="maven-version" value="3.5.0"/>
-  <property name="maven.dependencies.filters.file" location="lucene/build/maven.dependencies.filters.properties"/>
-
-  <property name="smokeTestRelease.dir" location="lucene/build/smokeTestRelease/dist"/>
-  <property name="smokeTestRelease.tmp" location="lucene/build/smokeTestRelease/tmp"/>
-  <property name="smokeTestRelease.testArgs" value=""/>
-
-  <target name="-projecthelp">
-    <java fork="false" classname="org.apache.tools.ant.Main" taskname="-">
-      <arg value="-projecthelp"/>
-      <arg value="-f"/>
-      <arg value="${ant.file}"/>
-    </java>
-  </target>
-
-  <target name="test-help" description="Test runner help">
-    <subant buildpath="lucene" target="test-help" inheritall="false" failonerror="true"/>
-  </target>
-
-  <target name="precommit" description="Run basic checks before committing"
-          depends="check-working-copy,validate,documentation-lint"/>
-
-  <target name="test" description="Test both Lucene and Solr" depends="resolve-groovy">
-    <mkdir dir="lucene/build" />
-    <tempfile property="tests.totals.tmpfile"
-          destdir="lucene/build"
-          prefix=".test-totals-"
-          suffix=".tmp"
-          deleteonexit="true"
-          createfile="true" />
-
-    <subant target="test" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset>
-        <propertyset refid="uptodate.and.compiled.properties"/>
-        <propertyref name="tests.totals.tmpfile" />
-      </propertyset>      
-    </subant>
-
-    <property name="tests.totals.toplevel" value="true" />
-    <antcall target="-check-totals" />
-  </target>
-
-  <target name="jacoco" depends="resolve-groovy" description="Generates JaCoCo code coverage reports">
-    <subant target="jacoco" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="pitest" depends="resolve-groovy" description="Run PITest on both Lucene and Solr">
-    <subant target="pitest" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="beast">
-    <fail message="The Beast only works inside of individual modules"/>
-  </target>
-
-  <target name="documentation" depends="resolve-markdown" description="Generate Lucene and Solr Documentation">
-    <subant target="documentation" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="documentation-lint" depends="resolve-markdown,-ecj-javadoc-lint-unsupported,-ecj-resolve" description="Validates the generated documentation (HTML errors, broken links,...)">
-    <subant target="documentation-lint" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="check-forbidden-apis" depends="-install-forbidden-apis" description="Check forbidden API calls in compiled class files.">
-    <subant target="check-forbidden-apis" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="validate" description="Validate dependencies, licenses, etc." depends="validate-source-patterns,resolve-groovy,rat-sources-typedef,-install-forbidden-apis">
-    <subant target="validate" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-    <subant buildpath="lucene" target="check-lib-versions" inheritall="false" failonerror="true">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-  
-  <target name="validate-source-patterns" description="Validate source code (invalid code patterns,...)" unless="disable.source-patterns" depends="resolve-groovy,rat-sources-typedef">
-    <groovy taskname="source-patterns" classpathref="rat.classpath" src="${common.dir}/tools/src/groovy/check-source-patterns.groovy"/>
-  </target>
-  
-  <target name="rat-sources" description="Runs rat across all sources and tests" depends="common.rat-sources">
-    <subant target="rat-sources" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="resolve" description="Resolves all dependencies">
-    <subant target="resolve" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <!-- lucene/test-framework and solr/test-framework are excluded from compilation -->
-  <target name="compile" description="Compile Lucene and Solr">
-    <subant target="compile" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="compile-core" description="Compile Lucene Core">
-    <subant target="compile-core" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="compile-test" description="Compile Lucene and Solr tests and test-frameworks">
-    <subant target="compile-test" inheritAll="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="jar" description="Build Lucene and Solr Jar files">
-    <subant target="jar" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml"/>
-      <fileset dir="solr" includes="build.xml"/>
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="jar-src" description="Build Lucene and Solr Source Jar files">
-    <subant target="jar-src" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml"/>
-      <fileset dir="solr" includes="build.xml"/>
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="get-maven-poms" depends="resolve" 
-          description="Copy Maven POMs from dev-tools/maven/ to maven-build/">
-    <ant dir="lucene" target="-get-maven-poms" inheritall="false"/>
-  </target>
-
-  <target name="clean-maven-build"
-          description="Clean up Maven POMs in working copy">
-    <delete failonerror="true" dir="${maven-build-dir}/"/>
-  </target>
-
-  <target name="generate-maven-artifacts" depends="resolve,resolve-groovy,resolve-markdown,install-maven-tasks"
-          description="Generate Maven Artifacts for Lucene and Solr">
-    <property name="maven.dist.dir"  location="dist/maven" />
-    <mkdir dir="${maven.dist.dir}" />
-    <ant dir="lucene" inheritall="false">
-      <target name="-unpack-lucene-tgz"/>
-      <target name="-filter-pom-templates"/>
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <ant dir="solr" target="-unpack-solr-tgz" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <subant target="-dist-maven" inheritall="false" failonerror="true">
-      <property name="maven.dist.dir"  location="${maven.dist.dir}" />
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="-install-maven-artifacts" depends="resolve,resolve-groovy,resolve-markdown,install-maven-tasks">
-    <ant dir="lucene" inheritall="false">
-      <target name="-unpack-lucene-tgz"/>
-      <target name="-filter-pom-templates"/>
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <ant dir="solr" target="-unpack-solr-tgz" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <subant target="-install-to-maven-local-repo" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="validate-maven-dependencies" depends="-install-maven-artifacts"
-          description="Validates maven dependencies, licenses, etc.">
-    <subant target="-validate-maven-dependencies" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml"/>
-      <fileset dir="solr" includes="build.xml"/>
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-  
-  <target name="run-maven-build" depends="get-maven-poms,install-maven-tasks,resolve-groovy" description="Runs the Maven build using automatically generated POMs">
-    <groovy src="${common.dir}/tools/src/groovy/run-maven-build.groovy"/>
-  </target>
-  
-  <target name="remove-maven-artifacts" description="Removes all Lucene/Solr Maven artifacts from the local repository">
-    <echo message="Removing all Lucene/Solr Maven artifacts from '${user.home}/.m2/repository'..."/>
-    <delete includeemptydirs="true">
-      <fileset dir="${user.home}/.m2/repository" erroronmissingdir="false">
-        <include name="org/apache/lucene/**"/>
-        <include name="org/apache/solr/**"/>
-      </fileset>
-    </delete>
-  </target>
-
-  <target name="netbeans" depends="resolve" description="Setup Netbeans configuration">
-    <pathconvert property="netbeans.fileset.sourcefolders" pathsep="|" dirsep="/">
-      <dirset dir="${basedir}/lucene" includes="**/src/java, **/src/examples, **/src/test, **/src/resources" 
-              excludes="tools/**, build/**" />
-      <dirset dir="${basedir}/solr" includes="**/src/java, **/src/examples, **/src/test, **/src/resources" 
-              excludes="build/**" />
-      <map from="${basedir}/" to=""/>
-    </pathconvert>
-    <!-- TODO: find a better way to exclude duplicate JAR files & fix the servlet-api mess! -->
-    <pathconvert property="netbeans.path.libs" pathsep=":" dirsep="/">
-      <fileset dir="${basedir}/lucene" includes="**/lib/*.jar" 
-               excludes="**/*servlet-api*.jar, tools/**, build/**"/>
-      <fileset dir="${basedir}/solr" includes="**/test-lib/*.jar,**/lib/*.jar" 
-               excludes="core/test-lib/*servlet-api*.jar, contrib/analysis-extras/**, test-framework/lib/junit*, test-framework/lib/ant*, test-framework/lib/randomizedtesting*, build/**, dist/**, package/**, server/solr-webapp/**" />
-      <map from="${basedir}/" to=""/>
-    </pathconvert>
-    <mkdir dir="nbproject"/>
-    <copy todir="nbproject" overwrite="true">
-      <fileset dir="dev-tools/netbeans/nbproject"/>
-    </copy>
-    <xslt in="${ant.file}" out="nbproject/project.xml" style="dev-tools/netbeans/nb-project.xsl" force="true">
-      <outputproperty name="indent" value="yes"/>
-      <param name="netbeans.fileset.sourcefolders" expression="${netbeans.fileset.sourcefolders}"/>
-      <param name="netbeans.path.libs" expression="${netbeans.path.libs}"/>
-      <param name="netbeans.source-level" expression="1.7"/>
-    </xslt>
-  </target>
-
-  <target name="clean-netbeans" description="Removes all Netbeans configuration files">
-    <delete dir="nbproject" failonerror="true"/>
-    <delete dir="nb-build" failonerror="true"/>
-  </target>
-
-  <target name="eclipse" depends="resolve" description="Setup Eclipse configuration">
-    <basename file="${basedir}" property="eclipseprojectname"/>
-    <copy file="dev-tools/eclipse/dot.project" tofile=".project" overwrite="false" encoding="UTF-8">
-      <filterset>
-        <filter token="ECLIPSEPROJECTNAME" value="${eclipseprojectname}"/>
-      </filterset>
-    </copy>
-    <copy overwrite="false" todir="eclipse-build" encoding="UTF-8">
-      <fileset dir="dev-tools/eclipse" includes="*.launch"/>
-      <filterset>
-        <filter token="ECLIPSEPROJECTNAME" value="${eclipseprojectname}"/>
-      </filterset>
-    </copy>
-    <mkdir dir=".settings"/>
-    <copy todir=".settings/" overwrite="true">
-      <fileset dir="dev-tools/eclipse/dot.settings" includes="*.prefs" />
-    </copy>
-
-    <pathconvert property="eclipse.fileset.sourcefolders" pathsep="|" dirsep="/">
-      <dirset dir="${basedir}/lucene" includes="**/src/java, **/src/resources, **/src/test, **/src/test-files, **/src/examples" excludes="tools/**, build/**" />
-      <dirset dir="${basedir}/solr" includes="**/src/java, **/src/resources, **/src/test, **/src/test-files, **/src/examples" excludes="build/**" />
-      <map from="${basedir}/" to=""/>
-    </pathconvert>
-    <!-- TODO: find a better way to exclude duplicate JAR files & fix the servlet-api mess! -->
-    <pathconvert property="eclipse.fileset.libs" pathsep="|" dirsep="/">
-      <fileset dir="${basedir}/lucene" includes="**/lib/*.jar" excludes="**/*servlet-api*.jar, tools/**, build/**"/>
-      <fileset dir="${basedir}/solr" includes="**/test-lib/*.jar,**/lib/*.jar" excludes="core/test-lib/*servlet-api*.jar, contrib/analysis-extras/**, test-framework/lib/junit*, test-framework/lib/ant*, test-framework/lib/randomizedtesting*, build/**, dist/**, package/**" />
-      <map from="${basedir}/" to=""/>
-    </pathconvert>
-    <pathconvert property="eclipse.fileset.webfolders" pathsep="|" dirsep="/">
-      <dirset dir="${basedir}/solr/server/contexts" excludes="**/*" />
-      <dirset dir="${basedir}/solr/server/etc" excludes="**/*" />
-      <dirset dir="${basedir}/solr/server/modules" excludes="**/*" />
-      <dirset dir="${basedir}/solr/server/solr" excludes="**/*" />
-      <dirset dir="${basedir}/solr/webapp/web" excludes="**/*" />
-      <map from="${basedir}/" to=""/>
-    </pathconvert>
-    <xslt in="${ant.file}" out=".classpath" style="dev-tools/eclipse/dot.classpath.xsl" force="true">
-      <outputproperty name="indent" value="yes"/>
-      <param name="eclipse.fileset.libs" expression="${eclipse.fileset.libs}"/>
-      <param name="eclipse.fileset.sourcefolders" expression="${eclipse.fileset.sourcefolders}"/>
-      <param name="eclipse.fileset.webfolders" expression="${eclipse.fileset.webfolders}"/>
-    </xslt>
-
-    <echo>
-      SUCCESS: You must right-click your project and choose Refresh.
-               Your project must use a Java 11 JRE.
-    </echo>
-  </target>
-
-  <target name="clean-eclipse" description="Removes all Eclipse configuration files">
-    <delete dir=".settings" failonerror="true"/>
-    <delete failonerror="true">
-      <fileset dir="." includes=".classpath,.project"/>
-    </delete>
-    <delete dir="eclipse-build" failonerror="true"/>
-  </target>
-
-  <target name="idea" depends="resolve" description="Setup IntelliJ IDEA configuration">
-    <condition property="idea.jdk.is.set">
-      <isset property="idea.jdk"/>
-    </condition>
-    <!-- Define ${idea.jdk} if it's not yet defined - otherwise literal "${idea.jdk}" is substituted -->
-    <property name="idea.jdk" value=""/>
-    <!-- delete those files first, so they are regenerated by the filtering below
-      (add more files with dynamic properties like versions here): -->
-    <delete dir=".idea" includes="misc.xml workspace.xml"/>
-    <!-- Copy files with filtering: -->
-    <copy todir="." overwrite="false" encoding="UTF-8">
-      <fileset dir="dev-tools/idea"/>
-      <filterset begintoken="subst.=&quot;" endtoken="&quot;">
-        <filter token="idea.jdk" value="${idea.jdk}"/>
-      </filterset>
-      <filterset>
-        <filter token="version" value="${version}"/>
-        <filter token="version.base" value="${version.base}"/>
-      </filterset>
-    </copy>
-    <antcall target="-post-idea-instructions"/>
-  </target>
-  
-  <target name="-post-idea-instructions" unless="idea.jdk.is.set">
-    <echo>
-To complete IntelliJ IDEA setup, you must manually configure
-File | Project Structure | Project | Project SDK.
-      
-You won't have to do this in the future if you define property
-$${idea.jdk}, e.g. in ~/lucene.build.properties, ~/build.properties
-or lucene/build.properties, with a value consisting of the
-following two XML attributes/values (adjust values according to
-JDKs you have defined locally - see 
-File | Project Structure | Platform Settings | SDKs):
-
-    idea.jdk = project-jdk-name="11" project-jdk-type="JavaSDK"
-    </echo>
-  </target>
-
-  <target name="clean-idea"
-          description="Removes all IntelliJ IDEA configuration files">
-    <delete dir=".idea" failonerror="true"/>
-    <delete failonerror="true">
-      <fileset dir="." includes="*.iml,*.ipr,*.iws"/>
-      <fileset dir="solr" includes="**/*.iml"/>
-      <fileset dir="lucene" includes="**/*.iml"/>
-    </delete>
-    <delete dir="idea-build" failonerror="true"/>
-  </target>
-
-  <target name="clean" description="Clean Lucene and Solr build dirs">
-    <delete dir="dist" />
-    <delete dir="${tests.heap-dump-dir}" />
-    <subant target="clean" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="clean-jars" description="Remove all JAR files from lib folders in the checkout">
-    <delete failonerror="true">
-      <fileset dir=".">
-        <include name="**/*.jar"/>
-        <exclude name="*/build/**"/>
-        <exclude name="*/dist/**"/>
-        <exclude name="*/package/**"/>
-        <exclude name="*/example/exampledocs/**"/>
-        <exclude name="gradle/**" />
-      </fileset>
-    </delete>
-  </target>
-
-  <target name="jar-checksums" description="Recompute SHA1 checksums for all JAR files.">
-    <subant target="jar-checksums" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <target name="-nightly-smoke-java12params" if="smokeTestRelease.java12">
-    <!-- convert path to UNIX style, so windows backslashes don't hurt escaping: -->
-    <pathconvert targetos="unix" property="-smokeTestRelease.java12params">
-      <regexpmapper from="^(.*)$" to="--test-java12 '\1'"/>
-      <path location="${smokeTestRelease.java12}"/>
-    </pathconvert>
-  </target>
-  
-  <target name="nightly-smoke" description="Builds an unsigned release and smoke tests it  (pass '-DsmokeTestRelease.java12=/path/to/jdk-12' to additionally test with Java 12 or later)"
-    depends="clean,resolve-groovy,resolve-markdown,install-maven-tasks,-nightly-smoke-java12params">
-    <fail message="To run nightly smoke, the JDK must be exactly Java 11, was: ${java.specification.version}">
-      <condition>
-        <not><equals arg1="${java.specification.version}" arg2="11"/></not>
-      </condition>
-    </fail>
-    <property name="-smokeTestRelease.java12params" value=""/><!-- (if not yet defined) -->
-    <exec executable="${python3.exe}" failonerror="true" taskname="python3">
-      <arg value="-V"/>
-    </exec>
-    <subant target="prepare-release-no-sign" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <!-- pass ${version.base} here to emulate a real release, without appendix like "-SNAPSHOT": -->
-      <property name="version" value="${version.base}" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-   </subant>
-    <mkdir dir="${smokeTestRelease.dir}"/>
-    <copy todir="${smokeTestRelease.dir}/lucene">
-      <fileset dir="lucene/dist"/>
-    </copy>
-    <copy todir="${smokeTestRelease.dir}/solr">
-      <fileset dir="solr/package"/>
-    </copy>
-    <local name="url"/>
-    <makeurl file="${smokeTestRelease.dir}" validate="false" property="url"/>
-    <exec executable="${python3.exe}" failonerror="true" taskname="smoker">
-      <arg value="-u"/>
-      <!-- Tell Python not to write any bytecode cache into the filesystem: -->
-      <arg value="-B"/>
-      <arg file="dev-tools/scripts/smokeTestRelease.py"/>
-      <arg line="${-smokeTestRelease.java12params}"/>
-      <arg value="--revision"/>
-      <arg value="skip"/>
-      <!-- pass ${version.base} here to emulate a real release, without appendix like "-SNAPSHOT": -->
-      <arg value="--version"/>
-      <arg value="${version.base}"/>
-      <arg value="--tmp-dir"/>
-      <arg file="${smokeTestRelease.tmp}"/>
-      <arg value="--not-signed"/>
-      <arg value="${url}"/>
-      <arg value="${smokeTestRelease.testArgs}"/>
-    </exec>
-    <delete dir="${smokeTestRelease.dir}"/>
-    <delete dir="${smokeTestRelease.tmp}"/>
-  </target>
-  
-  <macrodef xmlns:ivy="antlib:org.apache.ivy.ant" name="wc-checker">
-    <attribute name="failonmodifications"/><!-- fail if modifications were found, otherwise it only fails on unversioned files -->
-    <sequential>
-      <local name="wc.unversioned.files"/>
-      <local name="wc.modified.files"/>
-      <ivy:cachepath xmlns:ivy="antlib:org.apache.ivy.ant" transitive="true" resolveId="jgit" pathid="jgit.classpath">
-        <ivy:dependency org="org.eclipse.jgit" name="org.eclipse.jgit" rev="${jgit-version}" conf="default" />
-        <ivy:dependency org="org.slf4j" name="slf4j-nop" rev="1.7.2" conf="default" />
-      </ivy:cachepath>
-      <groovy taskname="wc-checker" classpathref="jgit.classpath" src="${common.dir}/tools/src/groovy/check-working-copy.groovy"/>
-      <fail if="wc.unversioned.files"
-        message="Source checkout is dirty (unversioned/missing files) after running tests!!! Offending files:${line.separator}${wc.unversioned.files}"/>
-      <fail message="Source checkout is modified!!! Offending files:${line.separator}${wc.modified.files}">
-        <condition>
-          <and>
-             <istrue value="@{failonmodifications}"/>
-             <isset property="wc.modified.files"/>
-          </and>
-        </condition>
-      </fail>
-    </sequential>
-  </macrodef>
-  
-  <target name="check-working-copy" description="Checks working copy for unversioned changes" depends="resolve-groovy">
-    <wc-checker failonmodifications="${is.jenkins.build}"/>
-  </target>
-
-  <target name="run-clover" description="Runs all tests to measure coverage and generates report (pass &quot;ANT_OPTS=-Xmx2G&quot; as environment)" depends="clean">
-    <antcall inheritAll="false">
-      <param name="run.clover" value="true"/>
-      <!-- must be 1, as clover does not like parallel test runs: -->
-      <param name="tests.jvms.override" value="1"/>
-      <!-- Also override some other props to be fast: -->
-      <param name="tests.multiplier" value="1"/>
-      <param name="tests.nightly" value="false"/>
-      <param name="tests.weekly" value="false"/>
-      <param name="tests.badapples" value="true"/>
-      <!-- The idea behind Clover is to determine test coverage, so be immune to failing tests: -->
-      <param name="tests.haltonfailure" value="false"/>
-      
-      <target name="clover"/>
-      <target name="test"/>
-      <target name="-generate-clover-reports"/>
-      
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </antcall>
-  </target>
-
-  <!--
-   Run after Junit tests.
-   
-   This target is in a separate file, as it needs to include common-build.xml,
-   but must run from top-level!
-   -->
-  <target name="-generate-clover-reports" depends="clover">
-    <fail unless="run.clover">Clover not enabled!</fail>
-    <mkdir dir="${clover.report.dir}"/>
-    <fileset dir="." id="clover.test.result.files">
-      <include name="*/build/**/test/TEST-*.xml"/>
-    </fileset>
-    <fileset dir="." id="clover.test.src.files">
-      <include name="**/src/test/**/*.java"/>
-      <!-- test framework source files are all test code: -->
-      <include name="*/test-framework/src/**/*.java"/>
-    </fileset>
-    <clover-report projectName="Apache Lucene/Solr">
-      <current outfile="${clover.report.dir}" title="Apache Lucene/Solr ${version}" numThreads="0">
-        <format type="html" filter="assert"/>
-        <testresults refid="clover.test.result.files"/>
-        <testsources refid="clover.test.src.files"/>
-      </current>
-      <current outfile="${clover.report.dir}/clover.xml" title="Apache Lucene/Solr ${version}">
-        <format type="xml" filter="assert"/>
-        <testresults refid="clover.test.result.files"/>
-        <testsources refid="clover.test.src.files"/>
-      </current>
-    </clover-report>
-    <echo>You can find the merged Lucene/Solr Clover report in '${clover.report.dir}'.</echo>
-  </target>
-
-  <target name="test-with-heapdumps" depends="resolve-groovy,-test-with-heapdumps-enabled,-test-with-heapdumps-disabled" description="Runs tests with heap dumps on OOM enabled (if VM supports this)"/>
-  
-  <condition property="vm.supports.heapdumps">
-    <or>
-      <contains string="${java.vm.name}" substring="hotspot" casesensitive="false"/>
-      <contains string="${java.vm.name}" substring="openjdk" casesensitive="false"/>
-    </or>
-  </condition>
-
-  <target name="-test-with-heapdumps-enabled" if="vm.supports.heapdumps">
-    <echo level="info" message="${java.vm.name}: Enabling heap dumps on OutOfMemoryError to dir '${tests.heap-dump-dir}'."/>
-    <mkdir dir="${tests.heap-dump-dir}"/>
-    <delete includeEmptyDirs="true">
-      <fileset dir="${tests.heap-dump-dir}"  includes="**/*"/>
-    </delete>
-    <antcall inheritAll="false" target="test">
-      <param name="tests.heapdump.args" value="-XX:+HeapDumpOnOutOfMemoryError &quot;-XX:HeapDumpPath=${tests.heap-dump-dir}&quot;"/>
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </antcall>
-    <pathconvert property="heapdumps.list" setonempty="false" pathsep="${line.separator}">
-      <fileset dir="${tests.heap-dump-dir}"/>
-      <map from="${tests.heap-dump-dir}${file.separator}" to="* "/>
-    </pathconvert>
-    <fail if="heapdumps.list" message="Some of the tests produced a heap dump, but did not fail. Maybe a suppressed OutOfMemoryError? Dumps created:${line.separator}${heapdumps.list}"/>
-    <delete dir="${tests.heap-dump-dir}"/>
-  </target>
-
-  <target name="-test-with-heapdumps-disabled" unless="vm.supports.heapdumps">
-    <echo level="warning" message="WARN: The used JVM (${java.vm.name}) does not support HPROF heap dumps on OutOfMemoryError."/>
-    <antcall target="test">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </antcall>
-  </target>
-
-  <target name="regenerate" description="Runs all code regenerators">
-    <subant target="regenerate" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <!-- todo:
-      <fileset dir="solr" includes="build.xml" />-->
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-
-  <!-- should only be called by jenkins, not precommit! -->
-  <target name="-check-after-regeneration" depends="resolve-groovy">
-    <wc-checker failonmodifications="true"/>
-  </target>
-
-  <!-- TODO: remove me when jenkins works -->
-  <target name="regenerateAndCheck" depends="regenerate,-check-after-regeneration"/>
-  
-  <target name="-append-all-modules-dependencies-properties">
-    <delete file="lucene/build/module.dependencies.properties"/>
-    <subant target="-append-module-dependencies-properties" inheritall="false" failonerror="true">
-      <fileset dir="lucene" includes="build.xml" />
-      <fileset dir="solr" includes="build.xml" />
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </subant>
-  </target>
-  
-  <!-- Jenkins tasks -->
-  <target name="-jenkins-base" depends="-print-java-info,clean,test-with-heapdumps,validate,documentation-lint,jar-checksums,check-working-copy"/>
-  
-  <target name="-print-java-info">
-    <echo level="info" taskname="java-info">java version &quot;${java.version}&quot;
-${java.runtime.name} (${java.runtime.version}, ${java.vendor})
-${java.vm.name} (${java.vm.version}, ${java.vm.vendor})
-Test args: [${args}]</echo>
-  </target>
-  
-  <target name="jenkins-hourly">
-    <antcall>
-      <param name="is.jenkins.build" value="true"/>
-      <param name="tests.haltonfailure" value="false"/>
-      <param name="tests.badapples" value="false"/>
-      <target name="-jenkins-base"/>
-    </antcall>
-  </target>
-  
-  <target name="jenkins-badapples">
-    <antcall>
-      <param name="is.jenkins.build" value="true"/>
-      <param name="tests.haltonfailure" value="false"/>
-      <param name="tests.badapples" value="true"/>
-      <target name="-jenkins-base"/>
-    </antcall>
-  </target>
-  
-  <target name="jenkins-nightly">
-    <antcall>
-      <param name="is.jenkins.build" value="true"/>
-      <param name="tests.haltonfailure" value="false"/>
-      <param name="tests.nightly" value="true"/>
-      <param name="tests.badapples" value="false"/>
-      <target name="-jenkins-base"/>
-    </antcall>
-  </target>
-
-  <target name="jenkins-nightly-badapples">
-    <antcall>
-      <param name="is.jenkins.build" value="true"/>
-      <param name="tests.haltonfailure" value="false"/>
-      <param name="tests.nightly" value="true"/>
-      <param name="tests.badapples" value="true"/>
-      <target name="-jenkins-base"/>
-    </antcall>
-  </target>
-
-  <target name="jenkins-maven-nightly" depends="-print-java-info,clean,clean-maven-build,resolve-groovy,resolve-markdown,install-maven-tasks">
-    <!-- step 1: build, install, validate and publish ANT-generated maven artifacts: -->
-    <antcall>
-      <param name="is.jenkins.build" value="true"/>
-      <target name="remove-maven-artifacts"/>
-      <target name="validate-maven-dependencies"/>
-      <target name="generate-maven-artifacts"/>
-    </antcall>
-    <!-- step 2: run the maven build to check that the pom templates also work to drive "mvn": -->
-    <antcall>
-      <param name="is.jenkins.build" value="true"/>
-      <target name="remove-maven-artifacts"/>
-      <target name="run-maven-build"/>
-    </antcall>
-  </target>
-  
-  <target name="jenkins-clover" depends="-print-java-info">
-    <antcall>
-      <param name="is.jenkins.build" value="true"/>
-      <target name="run-clover"/>
-    </antcall>
-  </target>
-
-  <!-- useless targets (override common-build.xml): -->
-  <target name="generate-test-reports"/>
-</project>
diff --git a/dev-tools/idea/.idea/ant.xml b/dev-tools/idea/.idea/ant.xml
deleted file mode 100644
index c270538..0000000
--- a/dev-tools/idea/.idea/ant.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="AntConfiguration">
-    <buildFile url="file://$PROJECT_DIR$/build.xml" />
-
-    <buildFile url="file://$PROJECT_DIR$/lucene/build.xml" />
-
-    <buildFile url="file://$PROJECT_DIR$/lucene/core/build.xml" />
-
-    <buildFile url="file://$PROJECT_DIR$/lucene/analysis/common/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/analysis/icu/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/analysis/kuromoji/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/analysis/morfologik/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/analysis/opennlp/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/analysis/phonetic/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/analysis/smartcn/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/analysis/stempel/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/benchmark/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/classification/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/codecs/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/demo/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/expressions/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/facet/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/grouping/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/highlighter/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/join/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/luke/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/luwak/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/memory/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/misc/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/queries/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/queryparser/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/replicator/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/sandbox/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/spatial/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/spatial-extras/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/suggest/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/test-framework/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/lucene/tools/build.xml" />
-
-    <buildFile url="file://$PROJECT_DIR$/solr/build.xml" />
-
-    <buildFile url="file://$PROJECT_DIR$/solr/core/build.xml" />
-
-    <buildFile url="file://$PROJECT_DIR$/solr/contrib/analysis-extras/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/solr/contrib/clustering/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/solr/contrib/dataimporthandler-extras/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/solr/contrib/dataimporthandler/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/solr/contrib/extraction/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/solr/contrib/langid/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/solr/contrib/prometheus-exporter/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/solr/contrib/velocity/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/solr/solrj/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/solr/test-framework/build.xml" />
-    <buildFile url="file://$PROJECT_DIR$/solr/webapp/build.xml" />
-  </component>
-</project>
diff --git a/dev-tools/idea/.idea/libraries/Ivy.xml b/dev-tools/idea/.idea/libraries/Ivy.xml
deleted file mode 100644
index 798dc0f..0000000
--- a/dev-tools/idea/.idea/libraries/Ivy.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<component name="libraryTable">
-  <library name="Ivy">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/lucene/tools/lib/ivy-2.3.0.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES />
-  </library>
-</component>
diff --git a/dev-tools/maven/README.maven b/dev-tools/maven/README.maven
deleted file mode 100644
index 0d9c7b7..0000000
--- a/dev-tools/maven/README.maven
+++ /dev/null
@@ -1,159 +0,0 @@
-====================================
-Lucene/Solr Maven build instructions
-====================================
-
-Contents:
-
-A. How to use nightly Jenkins-built Lucene/Solr Maven artifacts
-B. How to generate Maven artifacts
-C. How to deploy Maven artifacts to a repository
-D. How to use Maven to build Lucene/Solr
-
------
-
-A. How to use nightly Jenkins-built Lucene/Solr Maven artifacts
-
-   The most recently produced nightly Jenkins-built Lucene and Solr Maven
-   snapshot artifacts are available in the Apache Snapshot repository here:
-
-      https://repository.apache.org/snapshots
-
-   An example POM snippet:
-
-     <project ...>
-       ...
-       <repositories>
-         ...
-         <repository>
-           <id>apache.snapshots</id>
-           <name>Apache Snapshot Repository</name>
-           <url>https://repository.apache.org/snapshots</url>
-           <releases>
-             <enabled>false</enabled>
-           </releases>
-         </repository>
-
-
-B. How to generate Lucene/Solr Maven artifacts
-
-   Prerequisites: OpenJDK 11+ and Ant 1.8.2+
-
-   Run 'ant generate-maven-artifacts' to create an internal Maven
-   repository, including POMs, binary .jars, source .jars, and javadoc
-   .jars.
-
-   You can run the above command in three possible places: the top-level
-   directory; under lucene/; or under solr/.  From the top-level directory
-   or from lucene/, the internal repository will be located at dist/maven/.
-   From solr/, the internal repository will be located at package/maven/.
-
-
-C. How to deploy Maven artifacts to a repository
-
-   Prerequisites: OpenJDK 11+ and Ant 1.8.2+
-
-   You can deploy targets for all of Lucene/Solr, only Lucene, or only Solr,
-   as in B. above.  To deploy to a Maven repository, the command is the same
-   as in B. above, with the addition of two system properties:
-
-      ant -Dm2.repository.id=my-repo-id \
-          -Dm2.repository.url=https://example.org/my/repo \
-          generate-maven-artifacts
-
-   The repository ID given in the above command corresponds to a <server>
-   entry in either your ~/.m2/settings.xml or ~/.ant/settings.xml.  See
-   <https://maven.apache.org/settings.html#Servers> for more information.
-   (Note that as of version 2.1.3, Maven Ant Tasks cannot handle encrypted
-   passwords.)
-
-
-D. How to use Maven to build Lucene/Solr
-
-   In summary, to enable Maven builds, perform the following:
-
-         ant get-maven-poms
-         cd maven-build
-
-   The details, followed by some example Maven commands:
-
-   1. Prerequisites: OpenJDK 11+ and Maven 2.2.1 or 3.X
-
-   2. Make sure your sources are up to date.
-
-   3. Copy the Maven POM templates from under dev-tools/maven/ to the
-      maven-build/ directory using the following command from the top-level
-      directory:
-
-         ant get-maven-poms
-
-      Note that you will need to do this whenever changes to the POM
-      templates are committed.  For this reason, it's a good idea run
-      "ant get-maven-poms" after you update from origin.
-
-      The above command copies all of the POM templates from dev-tools/maven/,
-      filling in the project version with the default "X.X-SNAPSHOT".  If you
-      want the POMs and the Maven-built artifacts to have a version other than
-      the default, you can supply an alternate version on the command line
-      with the above command, e.g. "my-special-version":
-
-         ant -Dversion=my-special-version get-maven-poms
-
-      or to append "my-special-version" to the current base version, e.g. 5.0,
-      resulting in version "5.0-my-special-version":
-
-         ant -Ddev.version.suffix=my-special-version get-maven-poms
-
-      Note: if you change the version in the POMs, there is one test method
-      that will fail under maven-surefire-plugin:
-      o.a.l.index.TestCheckIndex#testLuceneConstantVersion().  It's safe to
-      @Ignore this test method, since it's just comparing the value of the
-      lucene.version system property (set in the maven-surefire-plugin
-      configuration in the lucene-core POM) against a hard-wired official
-      version (o.a.l.util.Constants.LUCENE_MAIN_VERSION).
-
-   4. To remove the maven-build/ directory and its contents, use the following
-      command from the top-level directory:
-
-         ant clean-maven-build
-
-   5. Please keep in mind that this is just a minimal Maven build. The resulting
-      artifacts are not the same as those created by the native Ant-based build.
-      It should be fine to enable Lucene builds in several Maven-based IDEs,
-      but should never be used for Lucene/Solr production usage, as they may lack
-      optimized class files (e.g., Java 9 MR-JAR support). To install Lucene/Solr
-      in your local repository, see instructions above.
-
-
-   Some example Maven commands you can use after you perform the above
-   preparatory steps:
-
-   - Compile, package, and install all binary artifacts to your local
-     repository:
-
-         mvn install
-
-     After compiling and packaging, but before installing each module's 
-     artifact, the above command will also run all the module's tests.
-     
-     The resulting artifacts are not the same as those created by the native
-     Ant-based build. They should never be used for Lucene/Solr production
-     usage, as they may lack optimized class files (e.g., Java 9 MR-JAR
-     support).
-
-   - Compile, package, and install all binary artifacts to your local
-     repository, without running any tests:
-
-         mvn -DskipTests install
-
-   - Compile, package, and install all binary and source artifacts to your
-     local repository, without running any tests:
-
-         mvn -DskipTests source:jar-no-fork install
-
-   - Run all tests:
-
-         mvn test
-
-   - Run all test methods defined in a test class:
-
-         mvn -Dtest=TestClassName test
diff --git a/dev-tools/maven/lucene/analysis/common/pom.xml.template b/dev-tools/maven/lucene/analysis/common/pom.xml.template
deleted file mode 100644
index 86d8202..0000000
--- a/dev-tools/maven/lucene/analysis/common/pom.xml.template
+++ /dev/null
@@ -1,86 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-analyzers-common</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Common Analyzers</name>
-  <description>Additional Analyzers</description>
-  <properties>
-    <module-directory>lucene/analysis/common</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-analyzers-common.internal.dependencies@
-@lucene-analyzers-common.external.dependencies@
-@lucene-analyzers-common.internal.test.dependencies@
-@lucene-analyzers-common.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>test-jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/analysis/icu/pom.xml.template b/dev-tools/maven/lucene/analysis/icu/pom.xml.template
deleted file mode 100644
index 34c343e..0000000
--- a/dev-tools/maven/lucene/analysis/icu/pom.xml.template
+++ /dev/null
@@ -1,76 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-analyzers-icu</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene ICU Analysis Components</name>
-  <description>    
-    Provides integration with ICU (International Components for Unicode) for
-    stronger Unicode and internationalization support.
-  </description>
-  <properties>
-    <module-directory>lucene/analysis/icu</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>${project.groupId}</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-analyzers-icu.internal.dependencies@
-@lucene-analyzers-icu.external.dependencies@
-@lucene-analyzers-icu.internal.test.dependencies@
-@lucene-analyzers-icu.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/analysis/kuromoji/pom.xml.template b/dev-tools/maven/lucene/analysis/kuromoji/pom.xml.template
deleted file mode 100644
index 21d92f7..0000000
--- a/dev-tools/maven/lucene/analysis/kuromoji/pom.xml.template
+++ /dev/null
@@ -1,75 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-analyzers-kuromoji</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Kuromoji Japanese Morphological Analyzer</name>
-  <description>
-    Lucene Kuromoji Japanese Morphological Analyzer
-  </description>
-  <properties>
-    <module-directory>lucene/analysis/kuromoji</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-analyzers-kuromoji.internal.dependencies@
-@lucene-analyzers-kuromoji.external.dependencies@
-@lucene-analyzers-kuromoji.internal.test.dependencies@
-@lucene-analyzers-kuromoji.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/analysis/morfologik/pom.xml.template b/dev-tools/maven/lucene/analysis/morfologik/pom.xml.template
deleted file mode 100644
index bd63d3a..0000000
--- a/dev-tools/maven/lucene/analysis/morfologik/pom.xml.template
+++ /dev/null
@@ -1,78 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-analyzers-morfologik</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Morfologik Polish Lemmatizer</name>
-  <description>
-    A dictionary-driven lemmatizer for Polish (includes morphosyntactic annotations)
-  </description>
-  <properties>
-    <module-directory>lucene/analysis/morfologik</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-analyzers-morfologik.internal.dependencies@
-@lucene-analyzers-morfologik.external.dependencies@
-@lucene-analyzers-morfologik.internal.test.dependencies@
-@lucene-analyzers-morfologik.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/analysis/nori/pom.xml.template b/dev-tools/maven/lucene/analysis/nori/pom.xml.template
deleted file mode 100644
index ac37a08..0000000
--- a/dev-tools/maven/lucene/analysis/nori/pom.xml.template
+++ /dev/null
@@ -1,75 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-analyzers-nori</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Nori Korean Morphological Analyzer</name>
-  <description>
-    Lucene Nori Korean Morphological Analyzer
-  </description>
-  <properties>
-    <module-directory>lucene/analysis/nori</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-analyzers-nori.internal.dependencies@
-@lucene-analyzers-nori.external.dependencies@
-@lucene-analyzers-nori.internal.test.dependencies@
-@lucene-analyzers-nori.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/analysis/opennlp/pom.xml.template b/dev-tools/maven/lucene/analysis/opennlp/pom.xml.template
deleted file mode 100644
index 4109a0a..0000000
--- a/dev-tools/maven/lucene/analysis/opennlp/pom.xml.template
+++ /dev/null
@@ -1,78 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-analyzers-opennlp</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene OpenNLP integration</name>
-  <description>
-    Lucene OpenNLP integration
-  </description>
-  <properties>
-    <module-directory>lucene/analysis/opennlp</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    @lucene-analyzers-opennlp.internal.dependencies@
-    @lucene-analyzers-opennlp.external.dependencies@
-    @lucene-analyzers-opennlp.internal.test.dependencies@
-    @lucene-analyzers-opennlp.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/analysis/phonetic/pom.xml.template b/dev-tools/maven/lucene/analysis/phonetic/pom.xml.template
deleted file mode 100644
index a8e8e93..0000000
--- a/dev-tools/maven/lucene/analysis/phonetic/pom.xml.template
+++ /dev/null
@@ -1,75 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-analyzers-phonetic</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Phonetic Filters</name>
-  <description>
-    Provides phonetic encoding via Commons Codec.
-  </description>
-  <properties>
-    <module-directory>lucene/analysis/phonetic</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-analyzers-phonetic.internal.dependencies@
-@lucene-analyzers-phonetic.external.dependencies@
-@lucene-analyzers-phonetic.internal.test.dependencies@
-@lucene-analyzers-phonetic.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/analysis/pom.xml.template b/dev-tools/maven/lucene/analysis/pom.xml.template
deleted file mode 100644
index f41aa06..0000000
--- a/dev-tools/maven/lucene/analysis/pom.xml.template
+++ /dev/null
@@ -1,55 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-analysis-modules-aggregator</artifactId>
-  <name>Lucene Analysis Modules aggregator POM</name>
-  <packaging>pom</packaging>
-  <modules>
-    <module>common</module>
-    <module>icu</module>
-    <module>kuromoji</module>
-    <module>morfologik</module>
-    <module>nori</module>
-    <module>opennlp</module>
-    <module>phonetic</module>
-    <module>smartcn</module>
-    <module>stempel</module>
-  </modules>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/analysis/smartcn/pom.xml.template b/dev-tools/maven/lucene/analysis/smartcn/pom.xml.template
deleted file mode 100644
index a795b76..0000000
--- a/dev-tools/maven/lucene/analysis/smartcn/pom.xml.template
+++ /dev/null
@@ -1,73 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-analyzers-smartcn</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Smart Chinese Analyzer</name>
-  <description>Smart Chinese Analyzer</description>
-  <properties>
-    <module-directory>lucene/analysis/smartcn</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-analyzers-smartcn.internal.dependencies@
-@lucene-analyzers-smartcn.external.dependencies@
-@lucene-analyzers-smartcn.internal.test.dependencies@
-@lucene-analyzers-smartcn.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/analysis/stempel/pom.xml.template b/dev-tools/maven/lucene/analysis/stempel/pom.xml.template
deleted file mode 100644
index f32e067..0000000
--- a/dev-tools/maven/lucene/analysis/stempel/pom.xml.template
+++ /dev/null
@@ -1,73 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-analyzers-stempel</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Stempel Analyzer</name>
-  <description>Stempel Analyzer</description>
-  <properties>
-    <module-directory>lucene/analysis/stempel</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-analyzers-stempel.internal.dependencies@
-@lucene-analyzers-stempel.external.dependencies@
-@lucene-analyzers-stempel.internal.test.dependencies@
-@lucene-analyzers-stempel.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/backward-codecs/pom.xml.template b/dev-tools/maven/lucene/backward-codecs/pom.xml.template
deleted file mode 100644
index 271276d..0000000
--- a/dev-tools/maven/lucene/backward-codecs/pom.xml.template
+++ /dev/null
@@ -1,88 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-backward-codecs</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Memory</name>
-  <description>
-    Codecs for older versions of Lucene.
-  </description>
-  <properties>
-    <module-directory>lucene/backward-codecs</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-backward-codecs.internal.dependencies@
-@lucene-backward-codecs.external.dependencies@
-@lucene-backward-codecs.internal.test.dependencies@
-@lucene-backward-codecs.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>test-jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/benchmark/pom.xml.template b/dev-tools/maven/lucene/benchmark/pom.xml.template
deleted file mode 100644
index 6c4a245..0000000
--- a/dev-tools/maven/lucene/benchmark/pom.xml.template
+++ /dev/null
@@ -1,86 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-benchmark</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Benchmark</name>
-  <description>Lucene Benchmarking Module</description>
-  <properties>
-    <module-directory>lucene/benchmark</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-benchmark.internal.dependencies@
-@lucene-benchmark.external.dependencies@
-@lucene-benchmark.internal.test.dependencies@
-@lucene-benchmark.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-      <testResource>
-        <directory>${module-path}</directory>
-        <includes>
-          <include>conf/**/*</include>
-        </includes>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>lucene-shared-check-sysout-forbidden-apis</id>
-            <phase>none</phase>  <!-- Block inherited execution -->
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/classification/pom.xml.template b/dev-tools/maven/lucene/classification/pom.xml.template
deleted file mode 100644
index 397d07d..0000000
--- a/dev-tools/maven/lucene/classification/pom.xml.template
+++ /dev/null
@@ -1,68 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-classification</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Classification</name>
-  <description>Lucene Classification</description>
-  <properties>
-    <module-directory>lucene/classification</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-classification.internal.dependencies@
-@lucene-classification.external.dependencies@
-@lucene-classification.internal.test.dependencies@
-@lucene-classification.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/codecs/pom.xml.template b/dev-tools/maven/lucene/codecs/pom.xml.template
deleted file mode 100644
index 269c23c..0000000
--- a/dev-tools/maven/lucene/codecs/pom.xml.template
+++ /dev/null
@@ -1,48 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-codecs-aggregator</artifactId>
-  <packaging>pom</packaging>
-  <name>Lucene codecs aggregator POM</name>
-  <modules>
-    <module>src/java</module>
-    <module>src/test</module>
-  </modules>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/codecs/src/java/pom.xml.template b/dev-tools/maven/lucene/codecs/src/java/pom.xml.template
deleted file mode 100644
index 4d2f027..0000000
--- a/dev-tools/maven/lucene/codecs/src/java/pom.xml.template
+++ /dev/null
@@ -1,85 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-codecs</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene codecs</name>
-  <description>
-    Codecs and postings formats for Apache Lucene.
-  </description>
-  <properties>
-    <module-directory>lucene/codecs</module-directory>
-    <relative-top-level>../../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}/src/java</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-@lucene-codecs.internal.dependencies@
-@lucene-codecs.external.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}</sourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/../resources</directory>
-      </resource>
-    </resources>
-    <testSourceDirectory/>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skip>true</skip> <!-- Tests are run from lucene-codecs-tests module -->
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <skip>true</skip> <!-- This skips test compilation - tests are run from lucene-codecs-tests module -->
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>lucene-shared-test-check-forbidden-apis</id>
-            <phase>none</phase>  <!-- Block inherited execution -->
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/codecs/src/test/pom.xml.template b/dev-tools/maven/lucene/codecs/src/test/pom.xml.template
deleted file mode 100644
index d64f899..0000000
--- a/dev-tools/maven/lucene/codecs/src/test/pom.xml.template
+++ /dev/null
@@ -1,84 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-codecs-tests</artifactId>
-  <name>Lucene codecs tests</name>
-  <packaging>jar</packaging>
-  <properties>
-    <module-directory>lucene/codecs</module-directory>
-    <relative-top-level>../../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}/src/test</module-path>
-  </properties>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-codecs</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-codecs.internal.test.dependencies@
-@lucene-codecs.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory/>
-    <testSourceDirectory>${module-path}</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>lucene-shared-check-forbidden-apis</id>
-            <phase>none</phase> <!-- Block inherited execution -->
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/core/pom.xml.template b/dev-tools/maven/lucene/core/pom.xml.template
deleted file mode 100644
index f06e1e2..0000000
--- a/dev-tools/maven/lucene/core/pom.xml.template
+++ /dev/null
@@ -1,48 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-core-aggregator</artifactId>
-  <packaging>pom</packaging>
-  <name>Lucene Core aggregator POM</name>
-  <modules>
-    <module>src/java</module>
-    <module>src/test</module>
-  </modules>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/core/src/java/pom.xml.template b/dev-tools/maven/lucene/core/src/java/pom.xml.template
deleted file mode 100644
index 89cdfe8..0000000
--- a/dev-tools/maven/lucene/core/src/java/pom.xml.template
+++ /dev/null
@@ -1,79 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-core</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Core</name>
-  <description>Apache Lucene Java Core</description>
-  <properties>
-    <module-directory>lucene/core</module-directory>
-    <relative-top-level>../../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}/src/java</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <build>
-    <sourceDirectory>${module-path}</sourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/../resources</directory>
-      </resource>
-    </resources>
-    <testSourceDirectory/>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skip>true</skip> <!-- Tests are run from lucene-codecs-tests module -->
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <skip>true</skip> <!-- This skips test compilation - tests are run from lucene-codecs-tests module -->
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>lucene-shared-test-check-forbidden-apis</id>
-            <phase>none</phase>  <!-- Block inherited execution -->
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/core/src/test/pom.xml.template b/dev-tools/maven/lucene/core/src/test/pom.xml.template
deleted file mode 100644
index d50e7e6..0000000
--- a/dev-tools/maven/lucene/core/src/test/pom.xml.template
+++ /dev/null
@@ -1,84 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-core-tests</artifactId>
-  <name>Lucene Core tests</name>
-  <packaging>jar</packaging>
-  <properties>
-    <module-directory>lucene/core</module-directory>
-    <relative-top-level>../../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}/src/test</module-path>
-  </properties>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-core.internal.test.dependencies@
-@lucene-core.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory/>
-    <testSourceDirectory>${module-path}</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>lucene-shared-check-forbidden-apis</id>
-            <phase>none</phase> <!-- Block inherited execution -->
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/demo/pom.xml.template b/dev-tools/maven/lucene/demo/pom.xml.template
deleted file mode 100644
index fc550ad..0000000
--- a/dev-tools/maven/lucene/demo/pom.xml.template
+++ /dev/null
@@ -1,85 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-demo</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Demo</name>
-  <description>This is the demo for Apache Lucene Java</description>
-  <properties>
-    <module-directory>lucene/demo</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-demo.internal.dependencies@
-@lucene-demo.external.dependencies@
-@lucene-demo.internal.test.dependencies@
-@lucene-demo.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>lucene-shared-check-sysout-forbidden-apis</id>
-            <phase>none</phase>  <!-- Block inherited execution -->
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/expressions/pom.xml.template b/dev-tools/maven/lucene/expressions/pom.xml.template
deleted file mode 100644
index 18ea18a..0000000
--- a/dev-tools/maven/lucene/expressions/pom.xml.template
+++ /dev/null
@@ -1,62 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-expressions</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Expressions</name>
-  <description>    
-     Dynamically computed values to sort/facet/search on based on a pluggable grammar.
-  </description>
-  <properties>
-    <module-directory>lucene/expressions</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-expressions.internal.dependencies@
-@lucene-expressions.external.dependencies@
-@lucene-expressions.internal.test.dependencies@
-@lucene-expressions.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/facet/pom.xml.template b/dev-tools/maven/lucene/facet/pom.xml.template
deleted file mode 100644
index 9d6d80d..0000000
--- a/dev-tools/maven/lucene/facet/pom.xml.template
+++ /dev/null
@@ -1,75 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-facet</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Facets</name>
-  <description>
-    Package for Faceted Indexing and Search
-  </description>
-  <properties>
-    <module-directory>lucene/facet</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-facet.internal.dependencies@
-@lucene-facet.external.dependencies@
-@lucene-facet.internal.test.dependencies@
-@lucene-facet.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/grouping/pom.xml.template b/dev-tools/maven/lucene/grouping/pom.xml.template
deleted file mode 100644
index 6314b72..0000000
--- a/dev-tools/maven/lucene/grouping/pom.xml.template
+++ /dev/null
@@ -1,68 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-grouping</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Grouping</name>
-  <description>Lucene Grouping Module</description>
-  <properties>
-    <module-directory>lucene/grouping</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-grouping.internal.dependencies@
-@lucene-grouping.external.dependencies@
-@lucene-grouping.internal.test.dependencies@
-@lucene-grouping.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/highlighter/pom.xml.template b/dev-tools/maven/lucene/highlighter/pom.xml.template
deleted file mode 100644
index ea31e63..0000000
--- a/dev-tools/maven/lucene/highlighter/pom.xml.template
+++ /dev/null
@@ -1,70 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-highlighter</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Highlighter</name>
-  <description>
-    This is the highlighter for apache lucene java
-  </description>
-  <properties>
-    <module-directory>lucene/highlighter</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-highlighter.internal.dependencies@
-@lucene-highlighter.external.dependencies@
-@lucene-highlighter.internal.test.dependencies@
-@lucene-highlighter.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/join/pom.xml.template b/dev-tools/maven/lucene/join/pom.xml.template
deleted file mode 100644
index 161e558..0000000
--- a/dev-tools/maven/lucene/join/pom.xml.template
+++ /dev/null
@@ -1,68 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-join</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Join</name>
-  <description>Lucene Join Module</description>
-  <properties>
-    <module-directory>lucene/join</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-join.internal.dependencies@
-@lucene-join.external.dependencies@
-@lucene-join.internal.test.dependencies@
-@lucene-join.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/memory/pom.xml.template b/dev-tools/maven/lucene/memory/pom.xml.template
deleted file mode 100644
index dcaeb12..0000000
--- a/dev-tools/maven/lucene/memory/pom.xml.template
+++ /dev/null
@@ -1,70 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-memory</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Memory</name>
-  <description>
-    High-performance single-document index to compare against Query
-  </description>
-  <properties>
-    <module-directory>lucene/memory</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-memory.internal.dependencies@
-@lucene-memory.external.dependencies@
-@lucene-memory.internal.test.dependencies@
-@lucene-memory.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/misc/pom.xml.template b/dev-tools/maven/lucene/misc/pom.xml.template
deleted file mode 100644
index a4bcac2..0000000
--- a/dev-tools/maven/lucene/misc/pom.xml.template
+++ /dev/null
@@ -1,68 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-misc</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Miscellaneous</name>
-  <description>Miscellaneous Lucene extensions</description>
-  <properties>
-    <module-directory>lucene/misc</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-     <scope>test</scope>
-    </dependency>
-@lucene-misc.internal.dependencies@
-@lucene-misc.external.dependencies@
-@lucene-misc.internal.test.dependencies@
-@lucene-misc.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/monitor/pom.xml.template b/dev-tools/maven/lucene/monitor/pom.xml.template
deleted file mode 100644
index 3d915e9..0000000
--- a/dev-tools/maven/lucene/monitor/pom.xml.template
+++ /dev/null
@@ -1,70 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-monitor</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Monitor</name>
-  <description>
-    High-performance single-document index to compare against Query
-  </description>
-  <properties>
-    <module-directory>lucene/monitor</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-monitor.internal.dependencies@
-@lucene-monitor.external.dependencies@
-@lucene-monitor.internal.test.dependencies@
-@lucene-monitor.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/pom.xml.template b/dev-tools/maven/lucene/pom.xml.template
deleted file mode 100644
index 1093bc4..0000000
--- a/dev-tools/maven/lucene/pom.xml.template
+++ /dev/null
@@ -1,127 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-solr-grandparent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-parent</artifactId>
-  <packaging>pom</packaging>
-  <name>Lucene parent POM</name>
-  <description>Lucene parent POM</description>
-  <properties>
-    <module-directory>lucene</module-directory>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <modules>
-    <module>core</module>
-    <module>backward-codecs</module>
-    <module>codecs</module>
-    <module>test-framework</module>
-    <module>analysis</module>
-    <module>benchmark</module>
-    <module>classification</module>
-    <module>demo</module>
-    <module>expressions</module>
-    <module>facet</module>
-    <module>grouping</module>
-    <module>highlighter</module>
-    <module>join</module>
-    <module>memory</module>
-    <module>misc</module>
-    <module>monitor</module>
-    <module>queries</module>
-    <module>queryparser</module>
-    <module>replicator</module>
-    <module>sandbox</module>
-    <module>spatial-extras</module>
-    <module>spatial3d</module>
-    <module>suggest</module>
-  </modules>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>lucene-shared-check-forbidden-apis</id>
-            <configuration>
-              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
-              <bundledSignatures>
-                <bundledSignature>jdk-unsafe</bundledSignature>
-                <bundledSignature>jdk-deprecated</bundledSignature>
-                <bundledSignature>jdk-non-portable</bundledSignature>
-                <bundledSignature>jdk-reflection</bundledSignature>
-              </bundledSignatures>
-              <signaturesFiles>
-                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/base.txt</signaturesFile>
-                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/lucene.txt</signaturesFile>
-              </signaturesFiles>
-            </configuration>
-            <goals>
-              <goal>check</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>lucene-shared-check-sysout-forbidden-apis</id>
-            <configuration>
-              <bundledSignatures>
-                <bundledSignature>jdk-system-out</bundledSignature>
-              </bundledSignatures>
-            </configuration>
-            <goals>
-              <goal>check</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>lucene-shared-test-check-forbidden-apis</id>
-            <configuration>
-              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
-              <bundledSignatures>
-                <bundledSignature>jdk-unsafe</bundledSignature>
-                <bundledSignature>jdk-deprecated</bundledSignature>
-                <bundledSignature>jdk-non-portable</bundledSignature>
-                <bundledSignature>jdk-reflection</bundledSignature>
-              </bundledSignatures>
-              <signaturesFiles>
-                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/tests.txt</signaturesFile>
-                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/base.txt</signaturesFile>
-                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/lucene.txt</signaturesFile>
-              </signaturesFiles>
-            </configuration>
-            <goals>
-              <goal>testCheck</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/queries/pom.xml.template b/dev-tools/maven/lucene/queries/pom.xml.template
deleted file mode 100644
index 778d75c..0000000
--- a/dev-tools/maven/lucene/queries/pom.xml.template
+++ /dev/null
@@ -1,68 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-queries</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Queries</name>
-  <description>Lucene Queries Module</description>
-  <properties>
-    <module-directory>lucene/queries</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-queries.internal.dependencies@
-@lucene-queries.external.dependencies@
-@lucene-queries.internal.test.dependencies@
-@lucene-queries.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/queryparser/pom.xml.template b/dev-tools/maven/lucene/queryparser/pom.xml.template
deleted file mode 100644
index 3f42d23..0000000
--- a/dev-tools/maven/lucene/queryparser/pom.xml.template
+++ /dev/null
@@ -1,86 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-queryparser</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene QueryParsers</name>
-  <description>Lucene QueryParsers module</description>
-  <properties>
-    <module-directory>lucene/queryparser</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-queryparser.internal.dependencies@
-@lucene-queryparser.external.dependencies@
-@lucene-queryparser.internal.test.dependencies@
-@lucene-queryparser.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>test-jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/replicator/pom.xml.template b/dev-tools/maven/lucene/replicator/pom.xml.template
deleted file mode 100644
index 3fbeb09..0000000
--- a/dev-tools/maven/lucene/replicator/pom.xml.template
+++ /dev/null
@@ -1,74 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-replicator</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Replicator</name>
-  <description>Lucene Replicator Module</description>
-  <properties>
-    <module-directory>lucene/replicator</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-replicator.internal.dependencies@
-@lucene-replicator.external.dependencies@
-@lucene-replicator.internal.test.dependencies@
-@lucene-replicator.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/sandbox/pom.xml.template b/dev-tools/maven/lucene/sandbox/pom.xml.template
deleted file mode 100644
index a59187b..0000000
--- a/dev-tools/maven/lucene/sandbox/pom.xml.template
+++ /dev/null
@@ -1,73 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-sandbox</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Sandbox</name>
-  <description>Lucene Sandbox</description>
-  <properties>
-    <module-directory>lucene/sandbox</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-sandbox.internal.dependencies@
-@lucene-sandbox.external.dependencies@
-@lucene-sandbox.internal.test.dependencies@
-@lucene-sandbox.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/spatial-extras/pom.xml.template b/dev-tools/maven/lucene/spatial-extras/pom.xml.template
deleted file mode 100644
index 9100ab4..0000000
--- a/dev-tools/maven/lucene/spatial-extras/pom.xml.template
+++ /dev/null
@@ -1,69 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-spatial-extras</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Spatial Extras</name>
-  <description>
-    Advanced Spatial Shape Strategies for Apache Lucene
-  </description>
-  <properties>
-    <module-directory>lucene/spatial-extras</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-spatial3d</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-@lucene-spatial-extras.internal.dependencies@
-@lucene-spatial-extras.external.dependencies@
-@lucene-spatial-extras.internal.test.dependencies@
-@lucene-spatial-extras.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/spatial3d/pom.xml.template b/dev-tools/maven/lucene/spatial3d/pom.xml.template
deleted file mode 100644
index 43b29a8..0000000
--- a/dev-tools/maven/lucene/spatial3d/pom.xml.template
+++ /dev/null
@@ -1,70 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-spatial3d</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Spatial 3D</name>
-  <description>
-    Lucene Spatial shapes implemented using 3D planar geometry
-  </description>
-  <properties>
-    <module-directory>lucene/spatial3d</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-spatial3d.internal.dependencies@
-@lucene-spatial3d.external.dependencies@
-@lucene-spatial3d.internal.test.dependencies@
-@lucene-spatial3d.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>test-jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/suggest/pom.xml.template b/dev-tools/maven/lucene/suggest/pom.xml.template
deleted file mode 100644
index f48f264..0000000
--- a/dev-tools/maven/lucene/suggest/pom.xml.template
+++ /dev/null
@@ -1,73 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-suggest</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Suggest</name>
-  <description>Lucene Suggest Module</description>
-  <properties>
-    <module-directory>lucene/suggest</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency> 
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@lucene-suggest.internal.dependencies@
-@lucene-suggest.external.dependencies@
-@lucene-suggest.internal.test.dependencies@
-@lucene-suggest.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/lucene/test-framework/pom.xml.template b/dev-tools/maven/lucene/test-framework/pom.xml.template
deleted file mode 100644
index df8a7bd..0000000
--- a/dev-tools/maven/lucene/test-framework/pom.xml.template
+++ /dev/null
@@ -1,109 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.lucene</groupId>
-  <artifactId>lucene-test-framework</artifactId>
-  <packaging>jar</packaging>
-  <name>Lucene Test Framework</name>
-  <description>Apache Lucene Java Test Framework</description>
-  <properties>
-    <module-directory>lucene/test-framework</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-@lucene-test-framework.internal.dependencies@
-@lucene-test-framework.external.dependencies@
-@lucene-test-framework.internal.test.dependencies@
-@lucene-test-framework.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-      <resource>
-        <directory>${project.build.sourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </resource>
-    </resources>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>lucene-shared-check-forbidden-apis</id>
-            <phase>none</phase> <!-- Block inherited execution -->
-          </execution>
-          <execution>
-            <id>lucene-shared-test-check-forbidden-apis</id>
-            <goals>
-              <goal>check</goal>
-              <goal>testCheck</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>lucene-shared-check-sysout-forbidden-apis</id>
-            <phase>none</phase>  <!-- Block inherited execution -->
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-  <repositories>
-    <repository>
-      <id>sonatype.releases</id>
-      <name>Sonatype Releases Repository</name>
-      <url>https://oss.sonatype.org/content/repositories/releases</url>
-      <releases>
-        <enabled>true</enabled>
-      </releases>
-      <snapshots>
-        <updatePolicy>never</updatePolicy>
-      </snapshots>
-    </repository>
-  </repositories>
-</project>
diff --git a/dev-tools/maven/solr/contrib/analysis-extras/pom.xml.template b/dev-tools/maven/solr/contrib/analysis-extras/pom.xml.template
deleted file mode 100644
index a0b3702..0000000
--- a/dev-tools/maven/solr/contrib/analysis-extras/pom.xml.template
+++ /dev/null
@@ -1,85 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-analysis-extras</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr Analysis Extras</name>
-  <description>Apache Solr Analysis Extras</description>
-  <properties>
-    <module-directory>solr/contrib/analysis-extras</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-analyzers-common</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <!-- This dependency cannot be put into solr-parent, because local        -->
-      <!-- dependencies are always ordered before inherited dependencies.       -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@solr-analysis-extras.internal.dependencies@
-@solr-analysis-extras.external.dependencies@
-@solr-analysis-extras.internal.test.dependencies@
-@solr-analysis-extras.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-      <testResource>
-        <directory>${top-level}/dev-tools/maven/solr</directory>
-        <includes>
-          <include>maven.testlogging.properties</include>
-        </includes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/contrib/analytics/pom.xml.template b/dev-tools/maven/solr/contrib/analytics/pom.xml.template
deleted file mode 100644
index afd53c1..0000000
--- a/dev-tools/maven/solr/contrib/analytics/pom.xml.template
+++ /dev/null
@@ -1,80 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-analytics</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr Analytics Package</name>
-  <description>
-    Apache Solr Content Analytics Package
-  </description>
-  <properties>
-    <module-directory>solr/contrib/analytics</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <!-- This dependency cannot be put into solr-parent, because local        -->
-      <!-- dependencies are always ordered before inherited dependencies.       -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    @solr-analytics.internal.dependencies@
-    @solr-analytics.external.dependencies@
-    @solr-analytics.internal.test.dependencies@
-    @solr-analytics.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-      <testResource>
-        <directory>${top-level}/dev-tools/maven/solr</directory>
-        <includes>
-          <include>maven.testlogging.properties</include>
-        </includes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/contrib/clustering/pom.xml.template b/dev-tools/maven/solr/contrib/clustering/pom.xml.template
deleted file mode 100644
index 831dede..0000000
--- a/dev-tools/maven/solr/contrib/clustering/pom.xml.template
+++ /dev/null
@@ -1,78 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-clustering</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr Clustering</name>
-  <description>Apache Solr Clustering</description>
-  <properties>
-    <module-directory>solr/contrib/clustering</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <!-- This dependency cannot be put into solr-parent, because local        -->
-      <!-- dependencies are always ordered before inherited dependencies.       -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@solr-clustering.internal.dependencies@
-@solr-clustering.external.dependencies@
-@solr-clustering.internal.test.dependencies@
-@solr-clustering.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-      <testResource>
-        <directory>${top-level}/dev-tools/maven/solr</directory>
-        <includes>
-          <include>maven.testlogging.properties</include>
-        </includes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/contrib/dataimporthandler-extras/pom.xml.template b/dev-tools/maven/solr/contrib/dataimporthandler-extras/pom.xml.template
deleted file mode 100644
index 21ccf5e..0000000
--- a/dev-tools/maven/solr/contrib/dataimporthandler-extras/pom.xml.template
+++ /dev/null
@@ -1,85 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-dataimporthandler-extras</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr DataImportHandler Extras</name>
-  <description>Apache Solr DataImportHandler Extras</description>
-  <properties>
-    <module-directory>solr/contrib/dataimporthandler-extras</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <!-- This dependency cannot be put into solr-parent, because local        -->
-      <!-- dependencies are always ordered before inherited dependencies.       -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-dataimporthandler</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-@solr-dataimporthandler-extras.internal.dependencies@
-@solr-dataimporthandler-extras.external.dependencies@
-@solr-dataimporthandler-extras.internal.test.dependencies@
-@solr-dataimporthandler-extras.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-      <testResource>
-        <directory>${top-level}/dev-tools/maven/solr</directory>
-        <includes>
-          <include>maven.testlogging.properties</include>
-        </includes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/contrib/dataimporthandler/pom.xml.template b/dev-tools/maven/solr/contrib/dataimporthandler/pom.xml.template
deleted file mode 100644
index 3992f9d..0000000
--- a/dev-tools/maven/solr/contrib/dataimporthandler/pom.xml.template
+++ /dev/null
@@ -1,91 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-dataimporthandler</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr DataImportHandler</name>
-  <description>Apache Solr DataImportHandler</description>
-  <properties>
-    <module-directory>solr/contrib/dataimporthandler</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <!-- This dependency cannot be put into solr-parent, because local        -->
-      <!-- dependencies are always ordered before inherited dependencies.       -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@solr-dataimporthandler.internal.dependencies@
-@solr-dataimporthandler.external.dependencies@
-@solr-dataimporthandler.internal.test.dependencies@
-@solr-dataimporthandler.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-      <testResource>
-        <directory>${top-level}/dev-tools/maven/solr</directory>
-        <includes>
-          <include>maven.testlogging.properties</include>
-        </includes>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>test-jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/contrib/extraction/pom.xml.template b/dev-tools/maven/solr/contrib/extraction/pom.xml.template
deleted file mode 100644
index 3ceaabe..0000000
--- a/dev-tools/maven/solr/contrib/extraction/pom.xml.template
+++ /dev/null
@@ -1,81 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-cell</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr Content Extraction Library</name>
-  <description>
-    Apache Solr Content Extraction Library integrates Apache Tika 
-    content extraction framework into Solr
-  </description>
-  <properties>
-    <module-directory>solr/contrib/extraction</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <!-- This dependency cannot be put into solr-parent, because local        -->
-      <!-- dependencies are always ordered before inherited dependencies.       -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@solr-cell.internal.dependencies@
-@solr-cell.external.dependencies@
-@solr-cell.internal.test.dependencies@
-@solr-cell.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-      <testResource>
-        <directory>${top-level}/dev-tools/maven/solr</directory>
-        <includes>
-          <include>maven.testlogging.properties</include>
-        </includes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/contrib/jaegertracer-configurator/pom.xml.template b/dev-tools/maven/solr/contrib/jaegertracer-configurator/pom.xml.template
deleted file mode 100644
index 7234185..0000000
--- a/dev-tools/maven/solr/contrib/jaegertracer-configurator/pom.xml.template
+++ /dev/null
@@ -1,80 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-jaegertracer-configurator</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr Jaeger Tracer Configurator Package</name>
-  <description>
-    Apache Solr Jaeger Tracer Configurator Package
-  </description>
-  <properties>
-    <module-directory>solr/contrib/jaegertracer-configurator</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <!-- This dependency cannot be put into solr-parent, because local        -->
-      <!-- dependencies are always ordered before inherited dependencies.       -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    @solr-jaegertracer-configurator.internal.dependencies@
-    @solr-jaegertracer-configurator.external.dependencies@
-    @solr-jaegertracer-configurator.internal.test.dependencies@
-    @solr-jaegertracer-configurator.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-      <testResource>
-        <directory>${top-level}/dev-tools/maven/solr</directory>
-        <includes>
-          <include>maven.testlogging.properties</include>
-        </includes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/contrib/langid/pom.xml.template b/dev-tools/maven/solr/contrib/langid/pom.xml.template
deleted file mode 100644
index 6543481..0000000
--- a/dev-tools/maven/solr/contrib/langid/pom.xml.template
+++ /dev/null
@@ -1,87 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-langid</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr Language Identifier</name>
-  <description>
-    This module is intended to be used while indexing documents.
-    It is implemented as an UpdateProcessor to be placed in an UpdateChain.
-    Its purpose is to identify language from documents and tag the document with language code.
-  </description>
-  <properties>
-    <module-directory>solr/contrib/langid</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <!-- This dependency cannot be put into solr-parent, because local        -->
-      <!-- dependencies are always ordered before inherited dependencies.       -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@solr-langid.internal.dependencies@
-@solr-langid.external.dependencies@
-@solr-langid.internal.test.dependencies@
-@solr-langid.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-      <testResource>
-        <directory>${top-level}/dev-tools/maven/solr</directory>
-        <includes>
-          <include>maven.testlogging.properties</include>
-        </includes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/contrib/ltr/pom.xml.template b/dev-tools/maven/solr/contrib/ltr/pom.xml.template
deleted file mode 100644
index 9506cb4..0000000
--- a/dev-tools/maven/solr/contrib/ltr/pom.xml.template
+++ /dev/null
@@ -1,80 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-ltr</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr Learning to Rank Package</name>
-  <description>
-    Apache Solr Learning to Rank Package
-  </description>
-  <properties>
-    <module-directory>solr/contrib/ltr</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <!-- This dependency cannot be put into solr-parent, because local        -->
-      <!-- dependencies are always ordered before inherited dependencies.       -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    @solr-ltr.internal.dependencies@
-    @solr-ltr.external.dependencies@
-    @solr-ltr.internal.test.dependencies@
-    @solr-ltr.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-      <testResource>
-        <directory>${top-level}/dev-tools/maven/solr</directory>
-        <includes>
-          <include>maven.testlogging.properties</include>
-        </includes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/contrib/pom.xml.template b/dev-tools/maven/solr/contrib/pom.xml.template
deleted file mode 100644
index d8280e4..0000000
--- a/dev-tools/maven/solr/contrib/pom.xml.template
+++ /dev/null
@@ -1,57 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-contrib-aggregator</artifactId>
-  <name>Apache Solr Contrib aggregator POM</name>
-  <packaging>pom</packaging>
-  <modules>
-    <module>analysis-extras</module>
-    <module>analytics</module>
-    <module>clustering</module>
-    <module>dataimporthandler</module>
-    <module>dataimporthandler-extras</module>
-    <module>extraction</module>
-    <module>jaegertracer-configurator</module>
-    <module>langid</module>
-    <module>ltr</module>
-    <module>prometheus-exporter</module>
-    <module>velocity</module>
-  </modules>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/contrib/prometheus-exporter/pom.xml.template b/dev-tools/maven/solr/contrib/prometheus-exporter/pom.xml.template
deleted file mode 100644
index 1d2d508..0000000
--- a/dev-tools/maven/solr/contrib/prometheus-exporter/pom.xml.template
+++ /dev/null
@@ -1,80 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-prometheus-exporter</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr Prometheus Exporter Package</name>
-  <description>
-    Apache Solr Prometheus Exporter Package
-  </description>
-  <properties>
-    <module-directory>solr/contrib/prometheus-exporter</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <!-- This dependency cannot be put into solr-parent, because local        -->
-      <!-- dependencies are always ordered before inherited dependencies.       -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    @solr-prometheus-exporter.internal.dependencies@
-    @solr-prometheus-exporter.external.dependencies@
-    @solr-prometheus-exporter.internal.test.dependencies@
-    @solr-prometheus-exporter.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-      <testResource>
-        <directory>${top-level}/dev-tools/maven/solr</directory>
-        <includes>
-          <include>maven.testlogging.properties</include>
-        </includes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/contrib/velocity/pom.xml.template b/dev-tools/maven/solr/contrib/velocity/pom.xml.template
deleted file mode 100644
index 82f12ee..0000000
--- a/dev-tools/maven/solr/contrib/velocity/pom.xml.template
+++ /dev/null
@@ -1,89 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-velocity</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr Velocity</name>
-  <description>Apache Solr Velocity</description>
-  <properties>
-    <module-directory>solr/contrib/velocity</module-directory>
-    <relative-top-level>../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <!-- This dependency cannot be put into solr-parent, because local        -->
-      <!-- dependencies are always ordered before inherited dependencies.       -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-@solr-velocity.internal.dependencies@
-@solr-velocity.external.dependencies@
-@solr-velocity.internal.test.dependencies@
-@solr-velocity.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-      <testResource>
-        <directory>${module-path}/src/test</directory>
-        <includes>
-          <include>velocity/*.properties</include>
-        </includes>
-      </testResource>
-      <testResource>
-        <directory>${top-level}/dev-tools/maven/solr</directory>
-        <includes>
-          <include>maven.testlogging.properties</include>
-        </includes>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/core/pom.xml.template b/dev-tools/maven/solr/core/pom.xml.template
deleted file mode 100644
index 7c4942a..0000000
--- a/dev-tools/maven/solr/core/pom.xml.template
+++ /dev/null
@@ -1,48 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-core-aggregator</artifactId>
-  <packaging>pom</packaging>
-  <name>Apache Solr Core aggregator POM</name>
-  <modules>
-    <module>src/java</module>
-    <module>src/test</module>
-  </modules>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/core/src/java/pom.xml.template b/dev-tools/maven/solr/core/src/java/pom.xml.template
deleted file mode 100644
index 5c63aef..0000000
--- a/dev-tools/maven/solr/core/src/java/pom.xml.template
+++ /dev/null
@@ -1,84 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-core</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr Core</name>
-  <description>Apache Solr Core</description>
-  <properties>
-    <module-directory>solr/core</module-directory>
-    <relative-top-level>../../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}/src/java</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-@solr-core.internal.dependencies@
-@solr-core.external.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}</sourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/../resources</directory>
-      </resource>
-    </resources>
-    <testSourceDirectory/>
-    <testResources/>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skip>true</skip> <!-- Tests are run from solr-core-tests module -->
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <skip>true</skip> <!-- This skips test compilation - tests are run from solr-core-tests module -->
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>solr-shared-test-check-forbidden-apis</id>
-            <phase>none</phase> <!-- Block inherited execution -->
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/core/src/test/pom.xml.template b/dev-tools/maven/solr/core/src/test/pom.xml.template
deleted file mode 100644
index 154f904..0000000
--- a/dev-tools/maven/solr/core/src/test/pom.xml.template
+++ /dev/null
@@ -1,155 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-core-tests</artifactId>
-  <name>Apache Solr Core tests</name>
-  <packaging>jar</packaging>
-  <properties>
-    <module-directory>solr/core</module-directory>
-    <relative-top-level>../../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}/src/test</module-path>
-  </properties>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <!-- This dependency cannot be put into solr-parent, because local        -->
-      <!-- dependencies are always ordered before inherited dependencies.       -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-queryparser</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-backward-codecs</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-@solr-core.internal.test.dependencies@
-@solr-core.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory/>
-    <!-- Instead of depending on solr-core module, use its output directory -->
-    <outputDirectory>../java/target/classes</outputDirectory>
-    <testSourceDirectory>${module-path}</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/../test-files</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-      <testResource>
-        <directory>${project.build.testSourceDirectory}</directory>
-        <excludes>
-          <exclude>**/*.java</exclude>
-        </excludes>
-      </testResource>
-      <testResource>
-        <directory>${top-level}/dev-tools/maven/solr</directory>
-        <includes>
-          <include>maven.testlogging.properties</include>
-        </includes>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>default-jar</id>
-            <!-- Skipping by binding the default execution ID to a non-existent phase only works in Maven 3, not 2. -->
-            <phase>none</phase>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-install-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <version>2.5.3</version>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>solr-shared-check-forbidden-apis</id>
-            <phase>none</phase> <!-- Block inherited execution -->
-          </execution>
-          <execution>
-            <id>solr-shared-test-check-forbidden-apis</id>
-            <configuration>
-              <excludes>
-                <!-- TODO: remove this - imported code -->
-                <exclude>org/apache/solr/internal/**/*.class</exclude>
-                <exclude>org/apache/hadoop/**</exclude>
-              </excludes>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/maven.testlogging.properties b/dev-tools/maven/solr/maven.testlogging.properties
deleted file mode 100644
index 4a4df0ea..0000000
--- a/dev-tools/maven/solr/maven.testlogging.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-handlers=java.util.logging.ConsoleHandler
-.level=SEVERE
diff --git a/dev-tools/maven/solr/pom.xml.template b/dev-tools/maven/solr/pom.xml.template
deleted file mode 100644
index 827eb26..0000000
--- a/dev-tools/maven/solr/pom.xml.template
+++ /dev/null
@@ -1,186 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.lucene</groupId>
-    <artifactId>lucene-solr-grandparent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-parent</artifactId>
-  <packaging>pom</packaging>
-  <name>Apache Solr parent POM</name>
-  <description>Apache Solr parent POM</description>
-  <modules>
-    <module>core</module>
-    <module>solrj</module>
-    <module>test-framework</module>
-    <module>contrib</module>
-  </modules>
-  <properties>
-    <module-directory>solr</module-directory>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <issueManagement>
-    <system>JIRA</system>
-    <url>https://issues.apache.org/jira/browse/SOLR</url>
-  </issueManagement>
-  <mailingLists>
-    <mailingList>
-      <name>Solr User List</name>
-      <subscribe>solr-user-subscribe@lucene.apache.org</subscribe>
-      <unsubscribe>solr-user-unsubscribe@lucene.apache.org</unsubscribe>
-      <archive>
-        https://mail-archives.apache.org/mod_mbox/solr-user/
-      </archive>
-    </mailingList>
-    <mailingList>
-      <name>Java Developer List</name>
-      <subscribe>dev-subscribe@lucene.apache.org</subscribe>
-      <unsubscribe>dev-unsubscribe@lucene.apache.org</unsubscribe>
-      <archive>https://mail-archives.apache.org/mod_mbox/lucene-dev/</archive>
-    </mailingList>
-    <mailingList>
-      <name>Java Commits List</name>
-      <subscribe>commits-subscribe@lucene.apache.org</subscribe>
-      <unsubscribe>commits-unsubscribe@lucene.apache.org</unsubscribe>
-      <archive>
-        https://mail-archives.apache.org/mod_mbox/lucene-java-commits/
-      </archive>
-    </mailingList>
-  </mailingLists>
-  <inceptionYear>2006</inceptionYear>
-  <repositories>
-    <repository>
-      <id>maven-restlet</id>
-      <name>Public online Restlet repository</name>
-      <url>https://maven.restlet.com</url>
-    </repository>
-    <repository>
-      <id>releases.cloudera.com</id>
-      <name>Cloudera Releases</name>
-      <url>https://repository.cloudera.com/artifactory/libs-release-local/</url>
-    </repository>
-  </repositories>
-  <build>
-    <pluginManagement>
-      <plugins>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-javadoc-plugin</artifactId>
-          <configuration>
-            <overview/>
-            <windowtitle>${project.name} ${project.version} API (${now.version})</windowtitle>
-            <doctitle>${project.name} ${project.version} API (${now.version})</doctitle>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-surefire-plugin</artifactId>
-          <configuration>
-            <systemPropertyVariables>
-              <tests.disableHdfs>${tests.disableHdfs}</tests.disableHdfs>
-            </systemPropertyVariables>
-          </configuration>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-    <plugins>
-      <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>solr-shared-check-forbidden-apis</id>
-            <configuration>
-              <!-- for simplicty with servlet-api and commons-io checks, disable this: -->
-              <failOnUnresolvableSignatures>false</failOnUnresolvableSignatures>
-              <bundledSignatures>
-                <bundledSignature>jdk-unsafe</bundledSignature>
-                <bundledSignature>jdk-deprecated</bundledSignature>
-                <bundledSignature>jdk-non-portable</bundledSignature>
-                <bundledSignature>jdk-reflection</bundledSignature>
-                <bundledSignature>commons-io-unsafe-@commons-io:commons-io.version@</bundledSignature>
-              </bundledSignatures>
-              <signaturesFiles>
-                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/base.txt</signaturesFile>
-                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/servlet-api.txt</signaturesFile>
-                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/solr.txt</signaturesFile>
-              </signaturesFiles>
-            </configuration>
-            <goals>
-              <goal>check</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>solr-shared-test-check-forbidden-apis</id>
-            <configuration>
-              <!-- for simplicty with servlet-api and commons-io checks, disable this: -->
-              <failOnUnresolvableSignatures>false</failOnUnresolvableSignatures>
-              <bundledSignatures>
-                <bundledSignature>jdk-unsafe</bundledSignature>
-                <bundledSignature>jdk-deprecated</bundledSignature>
-                <bundledSignature>jdk-non-portable</bundledSignature>
-                <bundledSignature>jdk-reflection</bundledSignature>
-                <bundledSignature>commons-io-unsafe-@commons-io:commons-io.version@</bundledSignature>
-              </bundledSignatures>
-              <signaturesFiles>
-                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/base.txt</signaturesFile>
-                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/servlet-api.txt</signaturesFile>
-                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/solr.txt</signaturesFile>
-                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/tests.txt</signaturesFile>
-              </signaturesFiles>
-            </configuration>
-            <goals>
-              <goal>testCheck</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <systemPropertyVariables>
-            <java.util.logging.config.file>${top-level}/solr/testlogging.properties</java.util.logging.config.file>
-          </systemPropertyVariables>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-  <profiles>
-    <profile>
-      <id>windows-tests-disableHdfs</id>
-      <activation>
-        <os><family>windows</family></os>
-      </activation>
-      <properties>
-        <tests.disableHdfs>true</tests.disableHdfs>
-      </properties>
-    </profile>
-  </profiles>
-</project>
diff --git a/dev-tools/maven/solr/solrj/pom.xml.template b/dev-tools/maven/solr/solrj/pom.xml.template
deleted file mode 100644
index 8dbccd5..0000000
--- a/dev-tools/maven/solr/solrj/pom.xml.template
+++ /dev/null
@@ -1,48 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-solrj-aggregator</artifactId>
-  <packaging>pom</packaging>
-  <name>Apache Solr Solrj aggregator POM</name>
-  <modules>
-    <module>src/java</module>
-    <module>src/test</module>
-  </modules>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/solrj/src/java/pom.xml.template b/dev-tools/maven/solr/solrj/src/java/pom.xml.template
deleted file mode 100644
index bb792c4..0000000
--- a/dev-tools/maven/solr/solrj/src/java/pom.xml.template
+++ /dev/null
@@ -1,78 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-solrj</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr Solrj</name>
-  <description>Apache Solr Solrj</description>
-  <properties>
-    <module-directory>solr/solrj</module-directory>
-    <relative-top-level>../../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}/src/java</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-@solr-solrj.internal.dependencies@
-@solr-solrj.external.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}</sourceDirectory>
-    <testSourceDirectory/>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skip>true</skip> <!-- Tests are run from solr-solrj-tests module -->
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <skip>true</skip> <!-- This skips test compilation - tests are run from solr-solrj-tests module -->
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>solr-shared-test-check-forbidden-apis</id>
-            <phase>none</phase> <!-- Block inherited execution -->
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/solrj/src/test/pom.xml.template b/dev-tools/maven/solr/solrj/src/test/pom.xml.template
deleted file mode 100644
index 93c14b3..0000000
--- a/dev-tools/maven/solr/solrj/src/test/pom.xml.template
+++ /dev/null
@@ -1,122 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-solrj-tests</artifactId>
-  <name>Apache Solr Solrj tests</name>
-  <packaging>jar</packaging>
-  <properties>
-    <module-directory>solr/solrj</module-directory>
-    <relative-top-level>../../../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}/src/test</module-path>
-  </properties>
-  <dependencies>
-    <dependency>
-      <!-- lucene-test-framework dependency must be declared before lucene-core -->
-      <!-- This dependency cannot be put into solr-parent, because local        -->
-      <!-- dependencies are always ordered before inherited dependencies.       -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-test-framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.solr</groupId>
-      <artifactId>solr-solrj</artifactId>
-      <scope>test</scope>
-    </dependency>
-@solr-solrj.internal.test.dependencies@
-@solr-solrj.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory/>
-    <!-- Instead of depending on solr-solrj module, use its output directory -->
-    <outputDirectory>../java/target/classes</outputDirectory>
-    <testSourceDirectory>${module-path}</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/../test-files</directory>
-      </testResource>
-      <testResource>
-        <directory>${top-level}/dev-tools/maven/solr</directory>
-        <includes>
-          <include>maven.testlogging.properties</include>
-        </includes>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>default-jar</id>
-            <!-- Skipping by binding the default execution ID to a non-existent phase only works in Maven 3, not 2. -->
-            <phase>none</phase>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-install-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <version>2.5.3</version>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>solr-shared-check-forbidden-apis</id>
-            <phase>none</phase> <!-- Block inherited execution -->
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/dev-tools/maven/solr/test-framework/pom.xml.template b/dev-tools/maven/solr/test-framework/pom.xml.template
deleted file mode 100644
index 3f55647..0000000
--- a/dev-tools/maven/solr/test-framework/pom.xml.template
+++ /dev/null
@@ -1,95 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-  http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.solr</groupId>
-    <artifactId>solr-parent</artifactId>
-    <version>@version@</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <groupId>org.apache.solr</groupId>
-  <artifactId>solr-test-framework</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache Solr Test Framework</name>
-  <description>Apache Solr Test Framework</description>
-  <properties>
-    <module-directory>solr/test-framework</module-directory>
-    <relative-top-level>../../..</relative-top-level>
-    <module-path>${relative-top-level}/${module-directory}</module-path>
-  </properties>
-  <scm>
-    <connection>scm:git:${vc-anonymous-base-url}</connection>
-    <developerConnection>scm:git:${vc-dev-base-url}</developerConnection>
-    <url>${vc-browse-base-url};f=${module-directory}</url>
-  </scm>
-  <dependencies>
-    <!-- These dependencies are compile scope because this is a test framework. -->
-    <dependency>
-      <!-- lucene-test-framework dependency must come before lucene-core -->
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-test-framework</artifactId>
-    </dependency>
-@solr-test-framework.internal.dependencies@
-@solr-test-framework.external.dependencies@
-@solr-test-framework.internal.test.dependencies@
-@solr-test-framework.external.test.dependencies@
-  </dependencies>
-  <build>
-    <sourceDirectory>${module-path}/src/java</sourceDirectory>
-    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${module-path}/src/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${module-path}/src/test-files</directory>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-       <plugin>
-        <groupId>de.thetaphi</groupId>
-        <artifactId>forbiddenapis</artifactId>
-        <executions>
-          <execution>
-            <id>solr-shared-check-forbidden-apis</id>
-            <phase>none</phase> <!-- Block inherited execution -->
-          </execution>
-          <execution>
-            <id>solr-shared-test-check-forbidden-apis</id>
-            <goals>
-              <goal>check</goal> <!-- NOT testCheck -->
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/lucene/BUILD.md b/lucene/BUILD.md
index 6810225..9846ed7 100644
--- a/lucene/BUILD.md
+++ b/lucene/BUILD.md
@@ -2,78 +2,67 @@
 
 ## Basic steps:
   
-  0. Install OpenJDK 11 (or greater), Ant 1.8.2+, Ivy 2.2.0
-  1. Download Lucene from Apache and unpack it
-  2. Connect to the top-level of your Lucene installation
+  0. Install OpenJDK 11 (or greater)
+  1. Download Lucene/Solr from Apache and unpack it
+  2. Connect to the top-level of your installation (parent of the lucene top-level directory)
   3. Install JavaCC (optional)
-  4. Run ant
+  4. Run gradle
 
-## Step 0) Set up your development environment (OpenJDK 11 or greater, Ant 1.8.2+, Ivy 2.2.0)
+## Step 0) Set up your development environment (OpenJDK 11 or greater)
 
 We'll assume that you know how to get and set up the JDK - if you
 don't, then we suggest starting at https://www.oracle.com/java/ and learning
 more about Java, before returning to this README. Lucene runs with
 Java 11 and later.
 
-Like many Open Source java projects, Lucene uses Apache Ant for build
-control.  Specifically, you MUST use Ant version 1.8.2+.
+Lucene uses [Gradle](https://gradle.org/) for build control; and includes Gradle wrapper script to download the correct version of it.
 
-Ant is "kind of like make without make's wrinkles".  Ant is
-implemented in java and uses XML-based configuration files.  You can
-get it at:
+NOTE: When Solr moves to a Top Level Project, it will no longer
+be necessary to download Solr to build Lucene. You can track
+progress at: https://issues.apache.org/jira/browse/SOLR-14497 
 
-  https://ant.apache.org
+NOTE: Lucene changed from Ant to Gradle as of release 9.0. Prior releases
+still use Ant.
 
-You'll need to download the Ant binary distribution.  Install it
-according to the instructions at:
-
-  https://ant.apache.org/manual
-
-Finally, you'll need to install ivy into your ant lib folder
-(~/.ant/lib). You can get it from http://ant.apache.org/ivy/.
-If you skip this step, the Lucene build system will offer to do it 
-for you.
-
-## Step 1) Download Lucene from Apache
+## Step 1) Download/Checkout Lucene source code
 
 We'll assume you already did this, or you wouldn't be reading this
 file.  However, you might have received this file by some alternate
 route, or you might have an incomplete copy of the Lucene, so: Lucene
-releases are available for download at:
+releases are available as part of Solr for download at:
 
-  https://www.apache.org/dyn/closer.cgi/lucene/java/
+  https://lucene.apache.org/solr/downloads.html
+  
+See the note above for why it is necessary currently to download Solr
 
 Download either a zip or a tarred/gzipped version of the archive, and
 uncompress it into a directory of your choice.
 
-## Step 2) From the command line, change (cd) into the top-level directory of your Lucene installation
+Or you can directly checkout the source code from GitHub:
 
-Lucene's top-level directory contains the build.xml file. By default,
-you do not need to change any of the settings in this file, but you do
-need to run ant from this location so it knows where to find build.xml.
+  https://github.com/apache/lucene-solr
 
-If you would like to change settings you can do so by creating one 
-or more of the following files and placing your own property settings
-in there:
+## Step 2) From the command line, change (cd) into the top-level directory of your Lucene/Solr installation
 
-    ~/lucene.build.properties
-    ~/build.properties
-    lucene-x.y/build.properties
+The parent directory for both Lucene and Solr contains the base configuration
+file for the combined build, as well as the "gradle wrapper" (gradlew) that
+makes invocation of Gradle easier. By default, you do not need to change any of 
+the settings in this file, but you do need to run Gradle from this location so 
+it knows where to find the necessary configurations.
 
-The first property which is found in the order with which the files are
-loaded becomes the property setting which is used by the Ant build
-system.
+The first time you run Gradle, it will create a file "gradle.properties" that
+contains machine-specific settings. Normally you can use this file as-is, but it
+can be modified if necessary. 
 
-NOTE: the ~ character represents your user account home directory.
+## Step 4) Run Gradle
 
-## Step 4) Run ant
+Assuming you can exectue "./gradlew help" should show you the main tasks that
+can be executed to show help sub-topics.
 
-Assuming you have ant in your PATH and have set ANT_HOME to the
-location of your ant installation, typing "ant" at the shell prompt
-and command prompt should run ant.  Ant will by default look for the
-"build.xml" file in your current directory, and compile Lucene.
+If you want to build Lucene independent of Solr, type:
+  ./gradlew -p lucene assemble
 
-If you want to build the documentation, type "ant documentation".
+If you want to build the documentation, type "./gradlew buildSite".
 
 For further information on Lucene, go to:
 
@@ -86,7 +75,3 @@ Please join the Lucene-User mailing list by visiting this site:
 Please post suggestions, questions, corrections or additions to this
 document to the lucene-user mailing list.
 
-This file was originally written by Steven J. Owens <pu...@darksleep.com>.
-This file was modified by Jon S. Stevens <jo...@latchkey.com>.
-
-Copyright (c) 2001-2020 The Apache Software Foundation.  All rights reserved.
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 6418f4d..d8bdf7f 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -255,11 +255,6 @@ Documentation
 
 * LUCENE-9424: Add a performance warning to AttributeSource.captureState javadocs (Haoyu Zhai)
 
-Other
----------------------
-
-* LUCENE-9497: Integrate Error Prone, a static analysis tool during compilation (Dawid Weiss, Varun Thacker)
-
 
 Other
 ---------------------
diff --git a/lucene/analysis/analysis-module-build.xml b/lucene/analysis/analysis-module-build.xml
deleted file mode 100644
index b6c88f7..0000000
--- a/lucene/analysis/analysis-module-build.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="analysis-module-build">
-
-  <!-- submodule build for analyzers.
-       ensures that each submodule is built under build/
-       consistent with its source structure so that
-       binary packaging makes sense -->
-
-  <basename property="submodule.project.name" file="${basedir}"/>
-  <dirname file="${ant.file.analysis-module-build}" property="analysis.dir"/>
-
-  <property name="build.dir" 
-        location="${analysis.dir}/../build/analysis/${submodule.project.name}"/>
-
-  <import file="../module-build.xml"/>
-
-  <target name="javadocs" depends="javadocs-analyzers-common, compile-core, check-javadocs-uptodate"
-          unless="javadocs-uptodate-${name}">
-    <invoke-module-javadoc>
-      <links>
-        <link href="../analyzers-common"/>
-      </links>
-    </invoke-module-javadoc>
-  </target>
-
-</project>
diff --git a/lucene/analysis/build.xml b/lucene/analysis/build.xml
deleted file mode 100644
index 6dc1500..0000000
--- a/lucene/analysis/build.xml
+++ /dev/null
@@ -1,172 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="analyzers" default="default">
-
-  <description>
-    Additional Analyzers
-      - common: Additional Analyzers
-      - icu: Analyzers that use functionality from ICU
-      - kuromoji: Japanese Morphological Analyzer
-      - morfologik: Morfologik Stemmer
-      - nori: Korean Morphological Analyzer
-      - smartcn: Smart Analyzer for Simplified Chinese Text
-      - stempel: Algorithmic Stemmer for Polish
-  </description>
-
-  <dirname file="${ant.file.analyzers}" property="analyzers.dir"/>
-
-  <macrodef name="forall-analyzers">
-    <attribute name="target" />
-    <sequential>
-      <subant target="@{target}" inheritall="false" failonerror="true">
-         <propertyset refid="uptodate.and.compiled.properties"/>
-        <fileset dir="${analyzers.dir}" includes="*/build.xml" />
-      </subant>
-    </sequential>
-  </macrodef>
-
-  <propertyset id="uptodate.and.compiled.properties" dynamic="true">
-    <propertyref regex=".*\.uptodate$$"/>
-    <propertyref regex=".*\.compiled$$"/>
-    <propertyref regex=".*\.loaded$$"/>
-    <propertyref name="tests.totals.tmpfile" />
-  </propertyset>
-
-  <target name="common">
-    <ant dir="common" />
-  </target>
-
-  <target name="icu">
-    <ant dir="icu" />
-  </target>
-
-  <target name="kuromoji">
-    <ant dir="kuromoji" />
-  </target>
-
-  <target name="morfologik">
-    <ant dir="morfologik" />
-  </target>
-
-  <target name="nori">
-    <ant dir="nori" />
-  </target>
-
-  <target name="opennlp">
-    <ant dir="opennlp" />
-  </target>
-
-  <target name="phonetic">
-    <ant dir="phonetic" />
-  </target>
-
-  <target name="smartcn">
-    <ant dir="smartcn" />
-  </target>
-
-  <target name="stempel">
-    <ant dir="stempel" />
-  </target>
-
-  <target name="default" depends="compile"/>
-  <target name="compile" depends="common,icu,kuromoji,morfologik,nori,opennlp,phonetic,smartcn,stempel" />
-
-  <target name="clean">
-    <forall-analyzers target="clean"/>
-  </target>
-  <target name="resolve">
-    <forall-analyzers target="resolve"/>
-  </target>
-  <target name="validate">
-    <forall-analyzers target="validate"/>
-  </target>
-  <target name="compile-core">
-    <forall-analyzers target="compile-core"/>
-  </target>
-  <target name="compile-test">
-    <forall-analyzers target="compile-test"/>
-  </target>
-  <target name="compile-tools">
-    <forall-analyzers target="compile-tools"/>
-  </target>
-  <target name="test">
-    <forall-analyzers target="test"/>
-  </target>
-  <target name="test-nocompile">
-    <fail message="Target 'test-nocompile' will not run recursively.  First change directory to the module you want to test."/>
-  </target>
-  <target name="beast">
-    <fail message="The Beast only works inside of individual modules"/>
-  </target>
-  <target name="jar">
-    <forall-analyzers target="jar-core"/>
-  </target>
-  <target name="jar-src">
-    <forall-analyzers target="jar-src"/>
-  </target>
-  <target name="jar-core" depends="jar"/>
-
-  <target name="build-artifacts-and-tests" depends="default,compile-test" />
-
-  <target name="-dist-maven">
-    <forall-analyzers target="-dist-maven"/>
-  </target>
-
-  <target name="-install-to-maven-local-repo">
-    <forall-analyzers target="-install-to-maven-local-repo"/>
-  </target>
-
-  <target name="-validate-maven-dependencies">
-    <forall-analyzers target="-validate-maven-dependencies"/>
-  </target>
-
-  <target name="javadocs">
-    <forall-analyzers target="javadocs"/>
-  </target>
-
-  <target name="javadocs-index.html">
-    <forall-analyzers target="javadocs-index.html"/>
-  </target>
-
-  <target name="rat-sources">
-    <forall-analyzers target="rat-sources"/>
-  </target>
-
-  <target name="-ecj-javadoc-lint">
-    <forall-analyzers target="-ecj-javadoc-lint"/>
-  </target>
-
-  <target name="regenerate">
-    <forall-analyzers target="regenerate"/>
-  </target>
-  
-  <target name="-append-module-dependencies-properties">
-    <forall-analyzers target="-append-module-dependencies-properties"/>
-  </target>
-  
-  <target name="check-forbidden-apis">
-    <forall-analyzers target="check-forbidden-apis"/>
-  </target>
-
-  <target name="jacoco">
-    <forall-analyzers target="jacoco"/>
-  </target>
-
-</project>
diff --git a/lucene/analysis/common/build.xml b/lucene/analysis/common/build.xml
deleted file mode 100644
index 21c5fda..0000000
--- a/lucene/analysis/common/build.xml
+++ /dev/null
@@ -1,125 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="analyzers-common" default="default">
-
-  <description>
-   Analyzers for indexing content in different languages and domains.
-  </description>
-
-  <!-- some files for testing that do not have license headers -->
-  <property name="rat.excludes" value="**/*.aff,**/*.dic,**/*.txt,**/charfilter/*.htm*,**/*LuceneResourcesWikiPage.html"/>
-  <property name="rat.additional-includes" value="src/tools/**"/>
-
-  <import file="../analysis-module-build.xml"/>
-
-  <property name="unicode-props-file" location="src/java/org/apache/lucene/analysis/util/UnicodeProps.java"/>
-
-  <!-- Because of a bug in JFlex's ant task, HTMLStripCharFilter has to be generated last.   -->
-  <!-- Otherwise the "%apiprivate" option used in its specification will leak into following -->
-  <!-- ant task invocations.                                                                 -->
-  <target name="jflex" depends="init,clean-jflex,-jflex-wiki-tokenizer,-jflex-ClassicAnalyzer,
-                                -jflex-UAX29URLEmailTokenizer,-jflex-HTMLStripCharFilter"/>
-
-  <target name="-jflex-HTMLStripCharFilter" depends="-install-jflex,generate-jflex-html-char-entities">
-    <run-jflex dir="src/java/org/apache/lucene/analysis/charfilter" name="HTMLStripCharFilter"/>
-    <fixcrlf  file="src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilter.java" encoding="UTF-8" eol="lf"/>
-  </target>
-
-  <target name="generate-jflex-html-char-entities">
-    <exec dir="src/java/org/apache/lucene/analysis/charfilter"
-          output="src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex"
-          executable="${python3.exe}" failonerror="true" logerror="true">
-      <!-- Tell Python not to write any bytecode cache into the filesystem: -->
-      <arg value="-B"/>
-      <arg value="htmlentity.py"/>
-    </exec>
-    <fixcrlf file="src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex" encoding="UTF-8" eol="lf"/>
-  </target>
-
-  <target name="-jflex-wiki-tokenizer" depends="-install-jflex">
-    <run-jflex dir="src/java/org/apache/lucene/analysis/wikipedia" name="WikipediaTokenizerImpl"/>
-  </target>
-
-  <target name="-jflex-ClassicAnalyzer" depends="-install-jflex">
-    <run-jflex dir="src/java/org/apache/lucene/analysis/standard" name="ClassicTokenizerImpl"/>
-  </target>
-
-  <target name="-jflex-UAX29URLEmailTokenizer" depends="-install-jflex">
-    <run-jflex-and-disable-buffer-expansion
-        dir="src/java/org/apache/lucene/analysis/standard" name="UAX29URLEmailTokenizerImpl"/>
-  </target>
-
-  <target name="clean-jflex">
-    <delete>
-      <fileset dir="src/java/org/apache/lucene/analysis/charfilter" includes="*.java">
-        <containsregexp expression="generated.*by.*JFlex"/>
-      </fileset>
-      <fileset dir="src/java/org/apache/lucene/analysis/wikipedia" includes="*.java">
-        <containsregexp expression="generated.*by.*JFlex"/>
-      </fileset>
-      <fileset dir="src/java/org/apache/lucene/analysis/standard" includes="**/*.java">
-        <containsregexp expression="generated.*by.*JFlex"/>
-      </fileset>
-    </delete>
-  </target>
-
-  <target xmlns:ivy="antlib:org.apache.ivy.ant" name="-resolve-icu4j" unless="icu4j.resolved" depends="ivy-availability-check,ivy-configure">
-    <loadproperties prefix="ivyversions" srcFile="${common.dir}/ivy-versions.properties"/>
-    <ivy:cachepath organisation="com.ibm.icu" module="icu4j" revision="${ivyversions./com.ibm.icu/icu4j}"
-      inline="true" conf="default" transitive="true" pathid="icu4j.classpath"/>
-    <property name="icu4j.resolved" value="true"/>
-  </target>
-
-  <target name="unicode-data" depends="-resolve-icu4j,resolve-groovy">
-    <groovy classpathref="icu4j.classpath" src="src/tools/groovy/generate-unicode-data.groovy"/>
-    <fixcrlf file="${unicode-props-file}" encoding="UTF-8"/>
-  </target>
-
-  <property name="tld.zones" value="https://www.internic.net/zones/root.zone"/>
-  <property name="tld.output" location="src/java/org/apache/lucene/analysis/standard/ASCIITLD.jflex-macro"/>
-
-  <target name="gen-tlds" depends="compile-tools">
-    <java
-      classname="org.apache.lucene.analysis.standard.GenerateJflexTLDMacros"
-      dir="."
-      fork="true"
-      failonerror="true">
-      <classpath>
-        <pathelement location="${build.dir}/classes/tools"/>
-      </classpath>
-      <arg value="${tld.zones}"/>
-      <arg value="${tld.output}"/>
-      <redirector alwayslog="true"/> <!-- stupid trick to get java class's stdout to ant's log -->
-    </java>
-  </target>
-
-  <target name="compile-tools" depends="common.compile-tools">
-    <compile
-      srcdir="src/tools/java"
-      destdir="${build.dir}/classes/tools">
-      <classpath refid="classpath"/>
-    </compile>
-  </target>
-
-  <target name="javadocs" depends="module-build.javadocs"/>
-
-  <target name="regenerate" depends="jflex,unicode-data"/>
-
-</project>
diff --git a/lucene/analysis/common/ivy.xml b/lucene/analysis/common/ivy.xml
deleted file mode 100644
index 9c5376b..0000000
--- a/lucene/analysis/common/ivy.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="analyzers-common"/>
-</ivy-module>
diff --git a/lucene/analysis/icu/build.xml b/lucene/analysis/icu/build.xml
deleted file mode 100644
index 32ab34d..0000000
--- a/lucene/analysis/icu/build.xml
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="analyzers-icu" default="default">
-
-  <description>
-   Analysis integration with ICU (International Components for Unicode).
-  </description>
-
-  <property name="rat.additional-includes" value="src/tools/**"/>
-
-  <import file="../analysis-module-build.xml"/>
-
-  <path id="icujar">
-     <fileset dir="lib"/>
-  </path>
-
-  <path id="classpath">
-    <pathelement path="${analyzers-common.jar}"/>
-    <path refid="icujar"/>
-    <path refid="base.classpath"/>
-  </path>
-
-  <path id="test.classpath">
-    <path refid="test.base.classpath" />
-    <pathelement path="src/test-files" />
-  </path>
-
-  <target name="compile-core" depends="jar-analyzers-common, common.compile-core" />
-
-  <property name="utr30.data.dir" location="src/data/utr30"/>
-  <target name="gen-utr30-data-files" depends="compile-tools">
-    <java
-        classname="org.apache.lucene.analysis.icu.GenerateUTR30DataFiles"
-        dir="${utr30.data.dir}"
-        fork="true"
-        failonerror="true">
-      <classpath>
-        <path refid="icujar"/>
-        <pathelement location="${build.dir}/classes/tools"/>
-      </classpath>
-    </java>
-  </target>
-
-  <property name="gennorm2.src.files"
-    value="nfc.txt nfkc.txt nfkc_cf.txt BasicFoldings.txt DiacriticFolding.txt DingbatFolding.txt HanRadicalFolding.txt NativeDigitFolding.txt"/>
-  <property name="gennorm2.tmp" value="${build.dir}/gennorm2/utr30.tmp"/>
-  <property name="gennorm2.dst" value="${resources.dir}/org/apache/lucene/analysis/icu/utr30.nrm"/>
-  <target name="gennorm2" depends="gen-utr30-data-files">
-    <echo>Note that the gennorm2 and icupkg tools must be on your PATH. These tools
-are part of the ICU4C package. See http://site.icu-project.org/ </echo>
-    <mkdir dir="${build.dir}/gennorm2"/>
-    <exec executable="gennorm2" failonerror="true">
-      <arg value="-v"/>
-      <arg value="-s"/>
-      <arg value="${utr30.data.dir}"/>
-      <arg line="${gennorm2.src.files}"/>
-      <arg value="-o"/>
-      <arg value="${gennorm2.tmp}"/>
-    </exec>
-    <!-- now convert binary file to big-endian -->
-    <exec executable="icupkg" failonerror="true">
-      <arg value="-tb"/>
-      <arg value="${gennorm2.tmp}"/>
-      <arg value="${gennorm2.dst}"/>
-    </exec>
-    <delete file="${gennorm2.tmp}"/>
-  </target>
-  
-  <property name="rbbi.src.dir" location="src/data/uax29"/>
-  <property name="rbbi.dst.dir" location="${resources.dir}/org/apache/lucene/analysis/icu/segmentation"/>
-  
-  <target name="genrbbi" depends="compile-tools">
-    <mkdir dir="${rbbi.dst.dir}"/>
-    <java
-      classname="org.apache.lucene.analysis.icu.RBBIRuleCompiler"
-      dir="."
-      fork="true"
-      failonerror="true">
-      <classpath>
-        <path refid="icujar"/>
-        <pathelement location="${build.dir}/classes/tools"/>
-      </classpath>
-      <assertions>
-        <enable package="org.apache.lucene"/>
-      </assertions>
-      <arg value="${rbbi.src.dir}"/>
-      <arg value="${rbbi.dst.dir}"/>
-    </java>
-  </target>
-
-  <target name="compile-tools" depends="init,common.compile-tools">
-    <compile
-      srcdir="src/tools/java"
-      destdir="${build.dir}/classes/tools">
-      <classpath refid="classpath"/>
-    </compile>
-  </target>
-
-  <target name="regenerate" depends="gen-utr30-data-files,gennorm2,genrbbi"/>
-
-</project>
diff --git a/lucene/analysis/icu/ivy.xml b/lucene/analysis/icu/ivy.xml
deleted file mode 100644
index 97b58f3..0000000
--- a/lucene/analysis/icu/ivy.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="analyzers-icu"/>
-  <configurations defaultconfmapping="compile->master">
-    <conf name="compile" transitive="false"/>
-  </configurations>
-  <dependencies>
-    <dependency org="com.ibm.icu" name="icu4j" rev="${/com.ibm.icu/icu4j}" conf="compile"/>
-    <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/> 
-  </dependencies>
-</ivy-module>
diff --git a/lucene/analysis/kuromoji/build.xml b/lucene/analysis/kuromoji/build.xml
deleted file mode 100644
index 7afa31d..0000000
--- a/lucene/analysis/kuromoji/build.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="analyzers-kuromoji" default="default" xmlns:ivy="antlib:org.apache.ivy.ant">
-
-  <description>
-    Japanese Morphological Analyzer
-  </description>
-
-  <!-- currently whether rat detects this as binary or not
-       is platform dependent?! -->
-  <property name="rat.excludes" value="**/*.txt,**/bocchan.utf-8"/>
-
-  <!-- we don't want to pull in ipadic/naist etc -->
-  <property name="ivy.default.configuration" value="default"/>
-  <import file="../analysis-module-build.xml"/> 
-
-  <!-- default configuration: uses mecab-ipadic -->
-  <property name="ipadic.type" value="ipadic"/>
-  <property name="ipadic.version" value="mecab-ipadic-2.7.0-20070801" />
-
-  <!-- alternative configuration: uses mecab-naist-jdic
-  <property name="ipadic.type" value="naist"/>
-  <property name="ipadic.version" value="mecab-naist-jdic-0.6.3b-20111013" />
-  -->
-  
-  <property name="dict.src.file" value="${ipadic.version}.tar.gz" />
-  <property name="dict.src.dir" value="${build.dir}/${ipadic.version}" />
-  <property name="dict.encoding" value="euc-jp"/>
-  <property name="dict.format" value="ipadic"/>
-  <property name="dict.normalize" value="false"/>
-  <property name="dict.target.dir" location="${resources.dir}"/>
-
-
-  <available type="dir" file="${build.dir}/${ipadic.version}" property="dict.available"/>
-
-  <path id="classpath">
-    <dirset dir="${build.dir}">
-      <include name="classes/java"/>
-    </dirset>
-    <pathelement path="${analyzers-common.jar}"/>
-    <path refid="base.classpath"/>
-  </path>
-
-  <target name="compile-core" depends="jar-analyzers-common, common.compile-core" />
-  <target name="download-dict" depends="ivy-availability-check,ivy-fail,ivy-configure" unless="dict.available">
-     <ivy:retrieve pattern="${build.dir}/${dict.src.file}" conf="${ipadic.type}" symlink="${ivy.symlink}"/>
-     <!-- TODO: we should checksum too -->
-     <gunzip src="${build.dir}/${dict.src.file}"/>
-     <untar src="${build.dir}/${ipadic.version}.tar" dest="${build.dir}"/>
-  </target>
-
-  <target name="patch-dict" depends="download-dict">
-    <patch patchfile="src/tools/patches/Noun.proper.csv.patch"
-           originalfile="${dict.src.dir}/Noun.proper.csv"/>
-  </target>
-
-  <target name="build-dict" depends="compile, patch-dict">
-    <sequential>
-      <delete verbose="true">
-        <fileset dir="${resources.dir}/org/apache/lucene/analysis/ja/dict" includes="**/*"/>
-      </delete>
-      <!-- TODO: optimize the dictionary construction a bit so that you don't need 1G -->
-      <java fork="true" failonerror="true" maxmemory="1g" classname="org.apache.lucene.analysis.ja.util.DictionaryBuilder">
-        <classpath refid="classpath"/>
-        <assertions>
-          <enable package="org.apache.lucene"/>
-        </assertions>
-        <arg value="${dict.format}"/>
-        <arg value="${dict.src.dir}"/>
-        <arg value="${dict.target.dir}"/>
-        <arg value="${dict.encoding}"/>
-        <arg value="${dict.normalize}"/>
-      </java>
-    </sequential>
-  </target>
-
-  <target name="compile-test" depends="module-build.compile-test"/>
-
-  <target name="regenerate" depends="build-dict"/>
-
-</project>
diff --git a/lucene/analysis/kuromoji/ivy.xml b/lucene/analysis/kuromoji/ivy.xml
deleted file mode 100644
index ee256b9..0000000
--- a/lucene/analysis/kuromoji/ivy.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="analyzers-kuromoji"/>
-  
-  <configurations defaultconfmapping="ipadic->default;naist->default"> <!-- 'master' conf not available to map to -->
-    <conf name="default" description="explicitly declare this configuration in order to not download dictionaries unless explicitly called for"/>
-    <conf name="ipadic" description="ipadic dictionary" transitive="false"/>
-    <conf name="naist" description="naist-jdic dictionary" transitive="false"/>
-  </configurations>
-
-  <dependencies>
-    <dependency org="mecab" name="mecab-ipadic" rev="${/mecab/mecab-ipadic}" conf="ipadic"> 
-      <artifact name="ipadic" type=".tar.gz" url="https://jaist.dl.sourceforge.net/project/mecab/mecab-ipadic/2.7.0-20070801/mecab-ipadic-2.7.0-20070801.tar.gz"/>
-    </dependency>
-    <dependency org="mecab" name="mecab-naist-jdic" rev="${/mecab/mecab-naist-jdic}" conf="naist">
-      <artifact name="mecab-naist-jdic" type=".tar.gz" url=" https://rwthaachen.dl.osdn.jp/naist-jdic/53500/mecab-naist-jdic-0.6.3b-20111013.tar.gz"/>
-    </dependency>
-    <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/>
-  </dependencies>
-</ivy-module>
diff --git a/lucene/analysis/morfologik/build.xml b/lucene/analysis/morfologik/build.xml
deleted file mode 100644
index fca0622..0000000
--- a/lucene/analysis/morfologik/build.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="analyzers-morfologik" default="default">
-  <description>
-    Analyzer for dictionary stemming, built-in Polish dictionary
-  </description>
-
-  <import file="../analysis-module-build.xml"/>
-
-  <path id="classpath">
-    <pathelement path="${analyzers-common.jar}"/>
-    <fileset dir="lib"/>
-    <path refid="base.classpath"/>
-  </path>
-  
-  
-  <path id="test.classpath">
-    <path refid="test.base.classpath" />
-    <pathelement path="src/test-files" />
-  </path>
-
-  <target name="compile-core" depends="jar-analyzers-common, common.compile-core" />
-</project>
diff --git a/lucene/analysis/morfologik/ivy.xml b/lucene/analysis/morfologik/ivy.xml
deleted file mode 100644
index f0cc234..0000000
--- a/lucene/analysis/morfologik/ivy.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="analyzers-morfologik"/>
-  <configurations defaultconfmapping="compile->master">
-    <conf name="compile" transitive="false"/>
-  </configurations>
-  <dependencies>
-    <dependency org="org.carrot2" name="morfologik-polish" rev="${/org.carrot2/morfologik-polish}" conf="compile"/>
-    <dependency org="org.carrot2" name="morfologik-fsa" rev="${/org.carrot2/morfologik-fsa}" conf="compile"/>
-    <dependency org="org.carrot2" name="morfologik-stemming" rev="${/org.carrot2/morfologik-stemming}" conf="compile"/>
-    <dependency org="ua.net.nlp" name="morfologik-ukrainian-search" rev="${/ua.net.nlp/morfologik-ukrainian-search}" conf="compile"/>
-    <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/> 
-  </dependencies>
-</ivy-module>
diff --git a/lucene/analysis/nori/build.xml b/lucene/analysis/nori/build.xml
deleted file mode 100644
index 7d5b0b9..0000000
--- a/lucene/analysis/nori/build.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="analyzers-nori" default="default" xmlns:ivy="antlib:org.apache.ivy.ant">
-
-  <description>
-    Korean Morphological Analyzer
-  </description>
-
-  <!-- currently whether rat detects this as binary or not
-       is platform dependent?! -->
-  <property name="rat.excludes" value="**/*.txt,**/bocchan.utf-8"/>
-
-  <!-- we don't want to pull in ipadic/naist etc -->
-  <property name="ivy.default.configuration" value="default"/>
-  <import file="../analysis-module-build.xml"/>
-
-  <!-- default configuration for Korean: uses mecab-ko-dic -->
-  <property name="dict.type" value="mecab-ko-dic"/>
-  <property name="dict.version" value="mecab-ko-dic-2.0.3-20170922" />
-
-  <property name="dict.src.file" value="${dict.version}.tar.gz" />
-  <property name="dict.src.dir" value="${build.dir}/${dict.version}" />
-  <property name="dict.encoding" value="utf-8"/>
-  <property name="dict.normalize" value="false"/>
-  <property name="dict.target.dir" location="${resources.dir}"/>
-
-  <available type="dir" file="${build.dir}/${dict.version}" property="mecab-ko.dict.available"/>
-
-  <path id="classpath">
-    <dirset dir="${build.dir}">
-      <include name="classes/java"/>
-    </dirset>
-    <pathelement path="${analyzers-common.jar}"/>
-    <path refid="base.classpath"/>
-  </path>
-
-  <target name="compile-core" depends="jar-analyzers-common, common.compile-core" />
-  <target name="download-dict" depends="ivy-availability-check,ivy-fail,ivy-configure" unless="mecab-ko.dict.available">
-    <ivy:retrieve pattern="${build.dir}/${dict.src.file}" conf="${dict.type}" symlink="${ivy.symlink}"/>
-    <!-- TODO: we should checksum too -->
-    <gunzip src="${build.dir}/${dict.src.file}"/>
-    <untar src="${build.dir}/${dict.version}.tar" dest="${build.dir}"/>
-  </target>
-
-  <target name="build-dict" depends="compile, download-dict">
-    <sequential>
-      <delete verbose="true">
-        <fileset dir="${resources.dir}/org/apache/lucene/analysis/ko/dict" includes="**/*"/>
-      </delete>
-      <!-- TODO: optimize the dictionary construction a bit so that you don't need 1G -->
-      <java fork="true" failonerror="true" maxmemory="1g" classname="org.apache.lucene.analysis.ko.util.DictionaryBuilder">
-        <classpath refid="classpath"/>
-        <assertions>
-          <enable package="org.apache.lucene"/>
-        </assertions>
-        <arg value="${dict.src.dir}"/>
-        <arg value="${dict.target.dir}"/>
-        <arg value="${dict.encoding}"/>
-        <arg value="${dict.normalize}"/>
-      </java>
-    </sequential>
-  </target>
-
-  <target name="compile-test" depends="module-build.compile-test"/>
-
-  <target name="regenerate" depends="build-dict"/>
-</project>
diff --git a/lucene/analysis/nori/ivy.xml b/lucene/analysis/nori/ivy.xml
deleted file mode 100644
index 8d32937..0000000
--- a/lucene/analysis/nori/ivy.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="analyzers-nori"/>
-
-  <configurations defaultconfmapping="mecab-ko-dic->default"> <!-- 'master' conf not available to map to -->
-    <conf name="default" description="explicitly declare this configuration in order to not download dictionaries unless explicitly called for"/>
-    <conf name="mecab-ko-dic" description="mecab-ko dictionary for Korean" transitive="false"/>
-  </configurations>
-
-  <dependencies>
-    <dependency org="mecab" name="mecab-ko-dic" rev="${/mecab/mecab-ko-dic}" conf="mecab-ko-dic">
-      <artifact name="mecab-ko-dic" type=".tar.gz" url="https://bitbucket.org/eunjeon/mecab-ko-dic/downloads/mecab-ko-dic-2.0.3-20170922.tar.gz" />
-    </dependency>
-    <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/>
-  </dependencies>
-</ivy-module>
diff --git a/lucene/analysis/opennlp/build.xml b/lucene/analysis/opennlp/build.xml
deleted file mode 100644
index 04f7eac..0000000
--- a/lucene/analysis/opennlp/build.xml
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="analyzers-opennlp" default="default">
-
-  <description>
-    OpenNLP Library Integration
-  </description>
-
-  <path id="opennlpjars">
-    <fileset dir="lib"/>
-  </path>
-
-  <property name="test.model.data.dir" location="src/tools/test-model-data"/>
-  <property name="tests.userdir" location="src/test-files"/>
-  <property name="test.model.dir" location="${tests.userdir}/org/apache/lucene/analysis/opennlp"/>
-
-  <import file="../analysis-module-build.xml"/>
-
-  <property name="analysis-extras.conf.dir"
-            location="${common.dir}/../solr/contrib/analysis-extras/src/test-files/analysis-extras/solr/collection1/conf"/>
-
-  <path id="classpath">
-    <pathelement path="${analyzers-common.jar}"/>
-    <path refid="opennlpjars"/>
-    <path refid="base.classpath"/>
-  </path>
-
-  <path id="test.classpath">
-    <path refid="test.base.classpath"/>
-    <pathelement path="${tests.userdir}"/>
-  </path>
-
-  <target name="compile-core" depends="jar-analyzers-common, common.compile-core" />
-
-  <!--
-    This does not create real NLP models, just small unencumbered ones for the unit tests.
-    All text taken from reuters corpus.
-    Tags applied with online demos at CCG Urbana-Champaign.
-    -->
-  <target name="train-test-models" description="Train all small test models for unit tests" depends="resolve">
-    <mkdir dir="${test.model.dir}"/>
-    <!-- https://opennlp.apache.org/docs/1.9.0/manual/opennlp.html#tools.sentdetect.training -->
-    <trainModel command="SentenceDetectorTrainer" lang="en" data="sentences.txt" model="en-test-sent.bin"/>
-    <copy file="${test.model.dir}/en-test-sent.bin" todir="${analysis-extras.conf.dir}"/>
-
-    <!-- https://opennlp.apache.org/docs/1.9.0/manual/opennlp.html#tools.tokenizer.training -->
-    <trainModel command="TokenizerTrainer" lang="en" data="tokenizer.txt" model="en-test-tokenizer.bin"/>
-    <copy file="${test.model.dir}/en-test-tokenizer.bin" todir="${analysis-extras.conf.dir}"/>
-
-    <!-- https://opennlp.apache.org/docs/1.9.0/manual/opennlp.html#tools.postagger.training -->
-    <trainModel command="POSTaggerTrainer" lang="en" data="pos.txt" model="en-test-pos-maxent.bin"/>
-
-    <!-- https://opennlp.apache.org/docs/1.9.0/manual/opennlp.html#tools.chunker.training -->
-    <trainModel command="ChunkerTrainerME" lang="en" data="chunks.txt" model="en-test-chunker.bin"/>
-
-    <!-- https://opennlp.apache.org/docs/1.9.0/manual/opennlp.html#tools.namefind.training -->
-    <trainModel command="TokenNameFinderTrainer" lang="en" data="ner.txt" model="en-test-ner.bin">
-      <extra-args>
-        <arg value="-params"/>
-        <arg value="ner_TrainerParams.txt"/>
-      </extra-args>
-    </trainModel>
-    <copy file="${test.model.dir}/en-test-ner.bin" todir="${analysis-extras.conf.dir}"/>
-
-    <!-- https://opennlp.apache.org/docs/1.9.0/manual/opennlp.html#tools.lemmatizer.training -->
-    <trainModel command="LemmatizerTrainerME" lang="en" data="lemmas.txt" model="en-test-lemmatizer.bin"/>
-  </target>
-
-  <macrodef name="trainModel">
-    <attribute name="command"/>
-    <attribute name="lang"/>
-    <attribute name="data"/>
-    <attribute name="model"/>
-    <element name="extra-args" optional="true"/>
-    <sequential>
-      <java classname="opennlp.tools.cmdline.CLI"
-            dir="${test.model.data.dir}"
-            fork="true"
-            failonerror="true">
-        <classpath>
-          <path refid="opennlpjars"/>
-        </classpath>
-
-        <arg value="@{command}"/>
-
-        <arg value="-lang"/>
-        <arg value="@{lang}"/>
-
-        <arg value="-data"/>
-        <arg value="@{data}"/>
-
-        <arg value="-model"/>
-        <arg value="${test.model.dir}/@{model}"/>
-
-        <extra-args/>
-      </java>
-    </sequential>
-  </macrodef>
-
-  <target name="regenerate" depends="train-test-models"/>
-</project>
diff --git a/lucene/analysis/opennlp/ivy.xml b/lucene/analysis/opennlp/ivy.xml
deleted file mode 100644
index cbbae64..0000000
--- a/lucene/analysis/opennlp/ivy.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="analyzers-opennlp" />
-  <configurations defaultconfmapping="compile->master">
-    <conf name="compile" transitive="false"/>
-  </configurations>
-  <dependencies>
-    <dependency org="org.apache.opennlp" name="opennlp-tools" rev="${/org.apache.opennlp/opennlp-tools}" transitive="false" conf="compile" />
-    <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}" />
-  </dependencies>
-</ivy-module>
diff --git a/lucene/analysis/phonetic/build.xml b/lucene/analysis/phonetic/build.xml
deleted file mode 100644
index 49d5726..0000000
--- a/lucene/analysis/phonetic/build.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="analyzers-phonetic" default="default">
-
-  <description>
-    Analyzer for indexing phonetic signatures (for sounds-alike search)
-  </description>
-
-  <import file="../analysis-module-build.xml"/>
-
-  <path id="classpath">
-    <pathelement path="${analyzers-common.jar}"/>
-    <fileset dir="lib"/>
-    <path refid="base.classpath"/>
-  </path>
-
-  <target name="compile-core" depends="jar-analyzers-common, common.compile-core" />
-</project>
diff --git a/lucene/analysis/phonetic/ivy.xml b/lucene/analysis/phonetic/ivy.xml
deleted file mode 100644
index df7d800..0000000
--- a/lucene/analysis/phonetic/ivy.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="analyzers-phonetic"/>
-  <configurations defaultconfmapping="compile->master">
-    <conf name="compile" transitive="false"/>
-  </configurations>
-  <dependencies>
-    <dependency org="commons-codec" name="commons-codec" rev="${/commons-codec/commons-codec}" conf="compile"/>
-    <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/> 
-  </dependencies>
-</ivy-module>
diff --git a/lucene/analysis/smartcn/build.xml b/lucene/analysis/smartcn/build.xml
deleted file mode 100644
index 01e0682..0000000
--- a/lucene/analysis/smartcn/build.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="analyzers-smartcn" default="default">
-
-  <description>
-    Analyzer for indexing Chinese
-  </description>
-
-  <import file="../analysis-module-build.xml"/>
-
-  <path id="classpath">
-    <pathelement path="${analyzers-common.jar}"/>
-    <path refid="base.classpath"/>
-  </path>
-
-  <target name="compile-core" depends="jar-analyzers-common, common.compile-core" />
-</project>
diff --git a/lucene/analysis/smartcn/ivy.xml b/lucene/analysis/smartcn/ivy.xml
deleted file mode 100644
index 842688d..0000000
--- a/lucene/analysis/smartcn/ivy.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="analyzers-smartcn"/>
-</ivy-module>
diff --git a/lucene/analysis/stempel/build.xml b/lucene/analysis/stempel/build.xml
deleted file mode 100644
index 64a823a..0000000
--- a/lucene/analysis/stempel/build.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="analyzers-stempel" default="default">
-
-  <description>
-    Analyzer for indexing Polish
-  </description>
-
-  <import file="../analysis-module-build.xml"/>
-
-  <path id="classpath">
-    <pathelement path="${analyzers-common.jar}"/>
-    <path refid="base.classpath"/>
-  </path>
-  
-  <target name="compile-core" depends="jar-analyzers-common, common.compile-core"/>
-</project>
diff --git a/lucene/analysis/stempel/ivy.xml b/lucene/analysis/stempel/ivy.xml
deleted file mode 100644
index afccee3..0000000
--- a/lucene/analysis/stempel/ivy.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="analyzers-stempel"/>
-</ivy-module>
diff --git a/lucene/backward-codecs/build.xml b/lucene/backward-codecs/build.xml
deleted file mode 100644
index 3de2979..0000000
--- a/lucene/backward-codecs/build.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<project name="backward-codecs" default="default">
-
-  <description>
-    Codecs for older versions of Lucene.
-  </description>
-
-  <import file="../module-build.xml"/>
-
-</project>
diff --git a/lucene/backward-codecs/ivy.xml b/lucene/backward-codecs/ivy.xml
deleted file mode 100644
index fe933f0..0000000
--- a/lucene/backward-codecs/ivy.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="backward-codecs"/>
-</ivy-module>
diff --git a/lucene/benchmark/build.xml b/lucene/benchmark/build.xml
deleted file mode 100644
index 2f53ff4..0000000
--- a/lucene/benchmark/build.xml
+++ /dev/null
@@ -1,289 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="benchmark" default="default">
-
-    <description>
-      System for benchmarking Lucene
-    </description>
-
-    <import file="../module-build.xml"/>
-    <property name="working.dir" location="work"/>
-
-    <!-- benchmark creates lots of sysout stuff, so dont run forbidden! -->
-    <target name="-check-forbidden-sysout"/>
-
-    <target name="check-files">
-        <available file="temp/news20.tar.gz" property="news20.exists"/>
-
-        <available file="${working.dir}/20_newsgroup" property="news20.expanded"/>
-
-        <available file="temp/reuters21578.tar.gz" property="reuters.exists"/>
-        <available file="${working.dir}/reuters" property="reuters.expanded"/>
-        <available file="${working.dir}/reuters-out" property="reuters.extracted"/>
-        <available file="temp/20news-18828.tar.gz" property="20news-18828.exists"/>
-        <available file="${working.dir}/20news-18828" property="20news-18828.expanded"/>
-        <available file="${working.dir}/mini_newsgroups" property="mini.expanded"/>
-        <available file="temp/allCountries.txt.bz2" property="geonames.exists"/>
-        <available file="${working.dir}/geonames" property="geonames.expanded"/>
-        
-        <available file="temp/enwiki-20070527-pages-articles.xml.bz2" property="enwiki.exists"/>
-        <available file="temp/enwiki-20070527-pages-articles.xml" property="enwiki.expanded"/>
-        <available file="${working.dir}/enwiki.txt" property="enwiki.extracted"/>
-      <available file="temp/${top.100k.words.archive.filename}"
-                   property="top.100k.words.archive.present"/>
-      <available file="${working.dir}/top100k-out" 
-                   property="top.100k.word.files.expanded"/>
-    </target>
-
-    <target name="enwiki-files" depends="check-files">
-        <mkdir dir="temp"/>
-        <antcall target="get-enwiki"/>
-        <antcall target="expand-enwiki"/>
-    </target>
-
-    <target name="get-enwiki" unless="enwiki.exists">
-        <get src="https://home.apache.org/~dsmiley/data/enwiki-20070527-pages-articles.xml.bz2"
-             dest="temp/enwiki-20070527-pages-articles.xml.bz2"/>
-    </target>
-
-    <target name="expand-enwiki"  unless="enwiki.expanded">
-        <bunzip2 src="temp/enwiki-20070527-pages-articles.xml.bz2" dest="temp"/>
-    </target>
-
-    <target name="geonames-files" depends="check-files" description="Get data for spatial.alg">
-        <mkdir dir="temp"/>
-        <antcall target="get-geonames"/>
-        <antcall target="expand-geonames"/>
-    </target>
-
-    <target name="get-geonames" unless="geonames.exists">
-        <!-- note: latest data is at: https://download.geonames.org/export/dump/allCountries.zip
-         and then randomize with: gsort -R -S 1500M file.txt > file_random.txt
-         and then compress with: bzip2 -9 -k file_random.txt -->
-      <get src="https://home.apache.org/~dsmiley/data/geonames_20130921_randomOrder_allCountries.txt.bz2"
-             dest="temp/allCountries.txt.bz2"/>
-    </target>
-
-    <target name="expand-geonames" unless="geonames.expanded">
-        <mkdir dir="${working.dir}/geonames"/>
-        <bunzip2 src="temp/allCountries.txt.bz2" dest="${working.dir}/geonames"/>
-    </target>
-
-    <target name="get-news-20" unless="20news-18828.exists">
-        <get src="https://www-2.cs.cmu.edu/afs/cs.cmu.edu/project/theo-20/www/data/news20.tar.gz"
-             dest="temp/news20.tar.gz"/>
-
-    </target>
-    <target name="get-reuters" unless="reuters.exists">
-        <!-- Please note: there is no HTTPS url. As this is only test data, we don't care: -->
-        <get src="http://www.daviddlewis.com/resources/testcollections/reuters21578/reuters21578.tar.gz"
-            dest="temp/reuters21578.tar.gz"/>
-    </target>
-
-    <target name="expand-news-20"  unless="news20.expanded">
-        <gunzip src="temp/news20.tar.gz" dest="temp"/>
-        <untar src="temp/news20.tar" dest="${working.dir}"/>
-    </target>
-    <target name="expand-reuters" unless="reuters.expanded">
-        <gunzip src="temp/reuters21578.tar.gz" dest="temp"/>
-        <mkdir dir="${working.dir}/reuters"/>
-        <untar src="temp/reuters21578.tar" dest="${working.dir}/reuters"/>
-        <delete >
-            <fileset dir="${working.dir}/reuters">
-                <include name="*.txt"/>
-            </fileset>
-        </delete>
-
-    </target>
-    <target name="extract-reuters" depends="check-files" unless="reuters.extracted">
-        <java classname="org.apache.lucene.benchmark.utils.ExtractReuters" maxmemory="1024M" fork="true">
-            <classpath refid="run.classpath"/>
-            <arg file="${working.dir}/reuters"/>
-            <arg file="${working.dir}/reuters-out"/>
-        </java>
-    </target>
-    <target name="get-20news-18828" unless="20news-18828.exists">
-        <!-- TODO: URL no longer works (404 Not found): -->
-        <get src="https://people.csail.mit.edu/u/j/jrennie/public_html/20Newsgroups/20news-18828.tar.gz"
-             dest="temp/20news-18828.tar.gz"/>
-
-    </target>
-    <target name="expand-20news-18828" unless="20news-18828.expanded">
-        <gunzip src="temp/20news-18828.tar.gz" dest="temp"/>
-        <untar src="temp/20news-18828.tar" dest="${working.dir}"/>
-    </target>
-    <target name="get-mini-news" unless="mini.exists">
-        <get src="https://kdd.ics.uci.edu/databases/20newsgroups/mini_newsgroups.tar.gz"
-             dest="temp/mini_newsgroups.tar.gz"/>
-    </target>
-    <target name="expand-mini-news" unless="mini.expanded">
-        <gunzip src="temp/mini_newsgroups.tar.gz" dest="temp"/>
-        <untar src="temp/mini_newsgroups.tar" dest="${working.dir}"/>
-    </target>
-
-  <property name="top.100k.words.archive.filename" 
-            value="top.100k.words.de.en.fr.uk.wikipedia.2009-11.tar.bz2"/>
-  <property name="top.100k.words.archive.base.url"
-            value="https://home.apache.org/~rmuir/wikipedia"/>
-  <target name="get-top-100k-words-archive" unless="top.100k.words.archive.present">
-    <mkdir dir="temp"/>
-      <get src="${top.100k.words.archive.base.url}/${top.100k.words.archive.filename}"
-           dest="temp/${top.100k.words.archive.filename}"/>
-  </target>
-  <target name="expand-top-100k-word-files" unless="top.100k.word.files.expanded">
-    <mkdir dir="${working.dir}/top100k-out"/>
-      <untar src="temp/${top.100k.words.archive.filename}"
-             overwrite="true" compression="bzip2" dest="${working.dir}/top100k-out"/>
-  </target>
-  
-  <target name="top-100k-wiki-word-files" depends="check-files">
-    <mkdir dir="${working.dir}"/>
-    <antcall target="get-top-100k-words-archive"/>
-    <antcall target="expand-top-100k-word-files"/>
-  </target>
-  
-    <target name="get-files" depends="check-files">
-        <mkdir dir="temp"/>
-        <antcall target="get-reuters"/>
-        <antcall target="expand-reuters"/>
-        <antcall target="extract-reuters"/>
-    </target>
-
-    <path id="classpath">
-      <pathelement path="${memory.jar}"/>
-      <pathelement path="${highlighter.jar}"/>
-      <pathelement path="${analyzers-common.jar}"/>
-      <pathelement path="${queryparser.jar}"/>
-      <pathelement path="${facet.jar}"/>
-      <pathelement path="${spatial-extras.jar}"/>
-      <pathelement path="${queries.jar}"/>
-      <pathelement path="${codecs.jar}"/>
-      <pathelement path="${join.jar}"/>
-      <path refid="base.classpath"/>
-      <fileset dir="lib"/>
-    </path>
-    <path id="run.classpath">
-        <path refid="classpath"/>
-        <pathelement location="${build.dir}/classes/java"/>
-        <pathelement path="${benchmark.ext.classpath}"/>
-    </path>
-
-    <target name="javadocs" depends="javadocs-memory,javadocs-highlighter,javadocs-analyzers-common,
-      javadocs-queryparser,javadocs-facet,javadocs-spatial-extras,compile-core,check-javadocs-uptodate"
-            unless="javadocs-uptodate-${name}">
-    <invoke-module-javadoc>
-      <links>
-        <link href="../memory"/>
-        <link href="../highlighter"/>
-        <link href="../analyzers-common"/>
-        <link href="../queryparser"/>
-        <link href="../facet"/>
-        <link href="../spatial-extras"/>
-      </links>
-    </invoke-module-javadoc>
-    </target>
-
-    <property name="task.alg" location="conf/micro-standard.alg"/>
-    <property name="task.mem" value="140M"/>
-
-    <target name="run-task" depends="compile,check-files,get-files" 
-     description="Run compound penalty perf test (optional: -Dtask.alg=your-algorithm-file -Dtask.mem=java-max-mem)">
-        <echo>Working Directory: ${working.dir}</echo>
-        <java classname="org.apache.lucene.benchmark.byTask.Benchmark" maxmemory="${task.mem}" fork="true">
-            <classpath refid="run.classpath"/>
-            <arg file="${task.alg}"/>
-        </java>
-    </target>
-
-    <target name="enwiki" depends="compile,check-files,enwiki-files">
-        <echo>Working Directory: ${working.dir}</echo>
-        <java classname="org.apache.lucene.benchmark.byTask.Benchmark" maxmemory="1024M" fork="true">
-            <assertions>
-              <enable/>
-            </assertions>
-            <classpath refid="run.classpath"/>
-            <arg file="conf/extractWikipedia.alg"/>
-        </java>
-    </target>
-
-  <property name="collation.alg.file" location="conf/collation.alg"/>
-  <property name="collation.output.file" 
-            value="${working.dir}/collation.benchmark.output.txt"/>
-  <property name="collation.jira.output.file" 
-            value="${working.dir}/collation.bm2jira.output.txt"/>
-  
-  <path id="collation.runtime.classpath">
-    <path refid="run.classpath"/>
-      <pathelement path="${analyzers-icu.jar}"/>
-  </path>
-  
-  <target name="collation" depends="compile,jar-analyzers-icu,top-100k-wiki-word-files">
-      <echo>Running benchmark with alg file: ${collation.alg.file}</echo>
-      <java fork="true" classname="org.apache.lucene.benchmark.byTask.Benchmark" 
-            maxmemory="${task.mem}" output="${collation.output.file}">
-        <classpath refid="collation.runtime.classpath"/>
-        <arg file="${collation.alg.file}"/>
-      </java>
-      <echo>Benchmark output is in file: ${collation.output.file}</echo>
-      <echo>Converting to JIRA table format...</echo>
-      <exec executable="${perl.exe}" output="${collation.jira.output.file}" failonerror="true">
-        <arg value="-CSD"/>
-        <arg value="scripts/collation.bm2jira.pl"/>
-        <arg value="${collation.output.file}"/>
-      </exec>
-      <echo>Benchmark output in JIRA table format is in file: ${collation.jira.output.file}</echo>
-  </target>
-  
-    <property name="shingle.alg.file" location="conf/shingle.alg"/>
-    <property name="shingle.output.file" 
-              value="${working.dir}/shingle.benchmark.output.txt"/>
-    <property name="shingle.jira.output.file" 
-              value="${working.dir}/shingle.bm2jira.output.txt"/>
-  
-    <path id="shingle.runtime.classpath">
-      <path refid="run.classpath"/>
-    </path>
-  
-    <target name="shingle" depends="compile,get-files">
-      <echo>Running benchmark with alg file: ${shingle.alg.file}</echo>
-      <java fork="true" classname="org.apache.lucene.benchmark.byTask.Benchmark" 
-            maxmemory="${task.mem}" output="${shingle.output.file}">
-        <classpath refid="run.classpath"/>
-        <arg file="${shingle.alg.file}"/>
-      </java>
-      <echo>Benchmark output is in file: ${shingle.output.file}</echo>
-      <echo>Converting to JIRA table format...</echo>
-      <exec executable="${perl.exe}" output="${shingle.jira.output.file}" failonerror="true">
-        <arg value="-CSD"/>
-        <arg value="scripts/shingle.bm2jira.pl"/>
-        <arg value="${shingle.output.file}"/>
-      </exec>
-      <echo>Benchmark output in JIRA table format is in file: ${shingle.jira.output.file}</echo>
-    </target>
-
-    <target name="init" depends="module-build.init,jar-memory,jar-highlighter,jar-analyzers-common,jar-queryparser,jar-facet,jar-spatial-extras,jar-codecs,jar-join"/>
-  
-    <target name="compile-test" depends="copy-alg-files-for-testing,module-build.compile-test"/>
-    <target name="copy-alg-files-for-testing" description="copy .alg files as resources for testing">
-      <copy todir="${build.dir}/classes/test/conf">
-        <fileset dir="conf"/>
-      </copy>
-    </target>
-</project>
diff --git a/lucene/benchmark/ivy.xml b/lucene/benchmark/ivy.xml
deleted file mode 100644
index 23c208c..0000000
--- a/lucene/benchmark/ivy.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="benchmark"/>
-  <configurations defaultconfmapping="compile->master">
-    <conf name="compile" transitive="false"/>
-  </configurations>
-  <dependencies>
-    <dependency org="org.apache.commons" name="commons-compress" rev="${/org.apache.commons/commons-compress}" conf="compile"/>
-    <dependency org="xerces" name="xercesImpl" rev="${/xerces/xercesImpl}" conf="compile"/>
-    <dependency org="net.sourceforge.nekohtml" name="nekohtml" rev="${/net.sourceforge.nekohtml/nekohtml}" conf="compile"/>
-    <dependency org="com.ibm.icu" name="icu4j" rev="${/com.ibm.icu/icu4j}" conf="compile"/>
-    <dependency org="org.locationtech.spatial4j" name="spatial4j" rev="${/org.locationtech.spatial4j/spatial4j}" conf="compile"/>
-    <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/> 
-  </dependencies>
-</ivy-module>
diff --git a/lucene/build.xml b/lucene/build.xml
deleted file mode 100644
index a5e17ad..0000000
--- a/lucene/build.xml
+++ /dev/null
@@ -1,586 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="lucene" default="default" basedir="."
-         xmlns:jacoco="antlib:org.jacoco.ant"
-         xmlns:artifact="antlib:org.apache.maven.artifact.ant">
-
-  <import file="common-build.xml"/>
-
-  <path id="classpath">
-    <pathelement location="${common.dir}/build/core/classes/java"/>
-  </path>
-
-  <patternset id="binary.build.dist.patterns"
-              includes="docs/,**/*.jar,**/*.war"
-              excludes="poms/**,**/*-src.jar,**/*-javadoc.jar"
-  />
-  <patternset id="binary.root.dist.patterns"
-              includes="LICENSE.txt,NOTICE.txt,README.md,
-                        MIGRATE.md,JRE_VERSION_MIGRATION.md,
-                        SYSTEM_REQUIREMENTS.md,
-                        CHANGES.txt,
-                        **/lib/*.jar,
-                        licenses/**,
-                        */docs/,**/README*"
-              excludes="build/**,site/**,tools/**,**/lib/*servlet-api*.jar,dev-docs/**"
-  />
-
-  <!-- ================================================================== -->
-  <!-- Prepares the build directory                                       -->
-  <!-- ================================================================== -->
-
-  <target name="test-core" description="Runs unit tests for the core Lucene code">
-    <ant dir="${common.dir}/core" target="test" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-  </target>
-
-  <!-- "-clover.load" is *not* a useless dependency. do not remove -->
-  <target name="test" depends="-clover.load, -init-totals, test-core, test-test-framework, test-modules, -check-totals"
-          description="Runs all unit tests (core, modules and back-compat)"
-  />
-  <target name="test-nocompile">
-    <fail message="Target 'test-nocompile' will not run recursively.  First change directory to the module you want to test."/>
-  </target>
-
-
-  <target name="pitest" depends="pitest-modules"
-          description="Runs pitests (core, modules and back-compat)"
-  />
-
-  <target name="beast">
-    <fail message="The Beast only works inside of individual modules"/>
-  </target>
-
-  <target name="compile-core" depends="compile-lucene-core"/>
-
-  <!-- lucene/test-framework is excluded from compilation -->
-  <target name="compile" depends="init,compile-lucene-core,compile-codecs"
-          description="Compiles core, codecs, and all modules">
-    <modules-crawl target="compile-core"/>
-  </target>
-
-  <!-- Validation (license/notice/api checks). -->
-  <target name="validate" depends="check-licenses,rat-sources,check-forbidden-apis" description="Validate stuff." />
-
-  <!-- Validation here depends on compile-tools: but we want to compile modules' tools too -->
-  <target name="compile-tools" depends="common.compile-tools">
-    <modules-crawl target="compile-tools"/>
-  </target>
-
-  <target name="check-licenses" depends="compile-tools,resolve,load-custom-tasks" description="Validate license stuff.">
-    <property name="skipRegexChecksum" value=""/>
-    <license-check-macro dir="${basedir}" licensedir="${common.dir}/licenses">
-      <additional-filters>
-        <replaceregex pattern="^jetty([^/]+)$" replace="jetty" flags="gi" />
-        <replaceregex pattern="slf4j-([^/]+)$" replace="slf4j" flags="gi" />
-        <replaceregex pattern="javax\.servlet([^/]+)$" replace="javax.servlet" flags="gi" />
-        <replaceregex pattern="(bcmail|bcprov)-([^/]+)$" replace="\1" flags="gi" />
-      </additional-filters>
-    </license-check-macro>
-  </target>
-
-  <target name="check-lib-versions" depends="compile-tools,resolve,load-custom-tasks"
-          description="Verify that the '/org/name' keys in ivy-versions.properties are sorted lexically and are neither duplicates nor orphans, and that all dependencies in all ivy.xml files use rev=&quot;$${/org/name}&quot; format.">
-    <lib-versions-check-macro dir="${common.dir}/.."
-                              centralized.versions.file="${common.dir}/ivy-versions.properties"
-                              top.level.ivy.settings.file="${common.dir}/top-level-ivy-settings.xml"
-                              ivy.resolution-cache.dir="${ivy.resolution-cache.dir}"
-                              ivy.lock-strategy="${ivy.lock-strategy}"
-                              common.build.dir="${common.build.dir}"
-                              ignore.conflicts.file="${common.dir}/ivy-ignore-conflicts.properties"/>
-  </target>
-
-  <!-- -install-forbidden-apis is *not* a useless dependency. do not remove -->
-  <target name="check-forbidden-apis" depends="-install-forbidden-apis" description="Check forbidden API calls in compiled class files">
-    <subant target="check-forbidden-apis" failonerror="true" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-      <fileset dir="core" includes="build.xml"/>
-      <fileset dir="test-framework" includes="build.xml"/>
-      <fileset dir="tools" includes="build.xml"/>
-    </subant>
-    <modules-crawl target="check-forbidden-apis"/>
-  </target>
-
-  <target name="resolve">
-    <sequential>
-      <ant dir="test-framework" target="resolve" inheritall="false">
-         <propertyset refid="uptodate.and.compiled.properties"/>
-      </ant>
-      <ant dir="${common.dir}/tools" target="resolve" inheritAll="false">
-         <propertyset refid="uptodate.and.compiled.properties"/>
-      </ant>
-      <modules-crawl target="resolve"/>
-    </sequential>
-  </target>
-
-  <target name="documentation" description="Generate all documentation"
-    depends="javadocs,changes-to-html,process-webpages"/>
-  <target name="javadoc" depends="javadocs"/>
-  <target name="javadocs" description="Generate javadoc" depends="javadocs-lucene-core, javadocs-modules, javadocs-test-framework"/>
-
-  <target name="documentation-lint" depends="-ecj-javadoc-lint,-documentation-lint-unsupported" if="documentation-lint.supported"
-          description="Validates the generated documentation (HTML errors, broken links,...)">
-    <!-- we use antcall here, otherwise ANT will run all dependent targets: -->
-    <antcall target="-documentation-lint"/>
-  </target>
-
-  <!-- we check for broken links across all documentation -->
-  <target name="-documentation-lint" depends="documentation">
-    <echo message="Checking for broken links..."/>
-    <check-broken-links dir="build/docs"/>
-    <echo message="Checking for missing docs..."/>
-    <!-- TODO: change this level=method -->
-    <check-missing-javadocs dir="build/docs" level="class"/>
-    <!-- too many classes to fix overall to just enable
-         the above to be level="method" right now, but we
-         can prevent the modules that don't have problems
-         from getting any worse -->
-    <!-- analyzers-common: problems -->
-    <check-missing-javadocs dir="build/docs/analyzers-icu" level="method"/>
-    <!-- analyzers-kuromoji: problems -->
-    <check-missing-javadocs dir="build/docs/analyzers-morfologik" level="method"/>
-    <check-missing-javadocs dir="build/docs/analyzers-phonetic" level="method"/>
-    <!-- analyzers-smartcn: problems -->
-    <check-missing-javadocs dir="build/docs/analyzers-stempel" level="method"/>
-    <!-- benchmark: problems -->
-    <check-missing-javadocs dir="build/docs/classification" level="method"/>
-    <!-- codecs: problems -->
-    <!-- core: problems -->
-    <check-missing-javadocs dir="build/docs/demo" level="method"/>
-    <check-missing-javadocs dir="build/docs/expressions" level="method"/>
-    <check-missing-javadocs dir="build/docs/facet" level="method"/>
-    <!-- grouping: problems -->
-    <!-- highlighter: problems -->
-    <check-missing-javadocs dir="build/docs/join" level="method"/>
-    <check-missing-javadocs dir="build/docs/memory" level="method"/>
-    <!-- misc: problems -->
-    <!-- queries: problems -->
-    <!-- queryparser: problems -->
-    <!-- sandbox: problems -->
-    <!-- spatial-extras: problems -->
-    <check-missing-javadocs dir="build/docs/suggest" level="method"/>
-    <!-- test-framework: problems -->
-
-    <!-- too much to fix core/ for now, but enforce full javadocs for key packages -->
-    <check-missing-javadocs dir="build/docs/core/org/apache/lucene/util/automaton" level="method"/>
-    <check-missing-javadocs dir="build/docs/core/org/apache/lucene/analysis" level="method"/>
-    <check-missing-javadocs dir="build/docs/core/org/apache/lucene/document" level="method"/>
-    <check-missing-javadocs dir="build/docs/core/org/apache/lucene/search/similarities" level="method"/>
-    <check-missing-javadocs dir="build/docs/core/org/apache/lucene/index" level="method"/>
-    <check-missing-javadocs dir="build/docs/core/org/apache/lucene/codecs" level="method"/>
-
-    <check-missing-javadocs dir="build/docs/spatial3d" level="method"/>
-  </target>
-  
-  <target name="-ecj-javadoc-lint" depends="compile,compile-test,-ecj-javadoc-lint-unsupported,-ecj-resolve" if="ecj-javadoc-lint.supported">
-    <subant target="-ecj-javadoc-lint" failonerror="true" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-      <fileset dir="core" includes="build.xml"/>
-      <fileset dir="test-framework" includes="build.xml"/>
-    </subant>
-    <modules-crawl target="-ecj-javadoc-lint"/>
-  </target>
-
-  <target name="process-webpages" depends="resolve-markdown">
-    <makeurl property="process-webpages.buildfiles" separator="|">
-      <fileset dir="." includes="**/build.xml" excludes="build.xml,analysis/*,build/**,tools/**,site/**"/>
-    </makeurl>
-    <property name="Codec.java" location="core/src/java/org/apache/lucene/codecs/Codec.java"/>
-    <loadfile srcfile="${Codec.java}" property="defaultCodec" encoding="UTF-8">
-      <filterchain>
-        <!--  private static Codec defaultCodec   =   LOADER    .   lookup    (   "LuceneXXX"                 )   ; -->
-        <containsregex pattern="^.*defaultCodec\s*=\s*LOADER\s*\.\s*lookup\s*\(\s*&quot;([^&quot;]+)&quot;\s*\)\s*;.*$" replace="\1"/>
-        <fixcrlf eol="unix" eof="remove" />
-        <deletecharacters chars="\n"/>
-      </filterchain>
-    </loadfile>
-
-    <!--
-      The XSL input file is ignored completely, but XSL expects one to be given,
-      so we pass ourself (${ant.file}) here. The list of module build.xmls is given
-      via string parameter, that must be splitted by the XSL at '|'.
-    --> 
-    <xslt in="${ant.file}" out="${javadoc.dir}/index.html" style="site/xsl/index.xsl" force="true">
-      <outputproperty name="method" value="html"/>
-      <outputproperty name="version" value="4.0"/>
-      <outputproperty name="encoding" value="UTF-8"/>
-      <outputproperty name="indent" value="yes"/>
-      <param name="buildfiles" expression="${process-webpages.buildfiles}"/>
-      <param name="version" expression="${version}"/>
-      <param name="defaultCodec" expression="${defaultCodec}"/>
-    </xslt>
-    
-    <markdown todir="${javadoc.dir}">
-      <fileset dir="." includes="MIGRATE.md,JRE_VERSION_MIGRATION.md,SYSTEM_REQUIREMENTS.md"/>
-      <globmapper from="*.md" to="*.html"/>
-    </markdown>
-
-    <copy todir="${javadoc.dir}">
-      <fileset dir="site/html"/>
-    </copy>
-  </target>
-  
-  <target name="javadocs-modules" description="Generate javadoc for modules classes">
-    <modules-crawl target="javadocs"/>
-  </target>
-
-  <!-- rat-sources-typedef is *not* a useless dependency. do not remove -->
-  <target name="rat-sources" depends="rat-sources-typedef,common.rat-sources">
-    <subant target="rat-sources" failonerror="true" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-      <fileset dir="core" includes="build.xml"/>
-      <fileset dir="test-framework" includes="build.xml"/>
-      <fileset dir="tools" includes="build.xml"/>
-    </subant>
-    <modules-crawl target="rat-sources"/>
-  </target>
-
-  <!-- ================================================================== -->
-  <!-- D I S T R I B U T I O N                                            -->
-  <!-- ================================================================== -->
-  <!--                                                                    -->
-  <!-- ================================================================== -->
-  <target name="package" depends="jar-core, jar-test-framework, build-modules, init-dist, documentation"/>
-
-  <target name="nightly" depends="test, package-tgz">
-  </target>
-
-  <!-- ================================================================== -->
-  <!-- Packages the distribution with zip                                 -->
-  <!-- ================================================================== -->
-  <!--                                                                    -->
-  <!-- ================================================================== -->
-  <target name="package-zip" depends="package"
-    description="--> Generates the Lucene distribution as .zip">
-
-    <delete file="${dist.dir}/lucene-${version}.zip"/>
-    <zip destfile="${dist.dir}/lucene-${version}.zip">
-      <zipfileset prefix="lucene-${version}" dir=".">
-        <patternset refid="binary.root.dist.patterns"/>
-      </zipfileset>
-      <zipfileset prefix="lucene-${version}" dir="${build.dir}">
-        <patternset refid="binary.build.dist.patterns"/>
-      </zipfileset>
-      <zipfileset prefix="lucene-${version}" dir="${build.dir}" includes="**/*.sh,**/*.bat" filemode="755"/>
-    </zip>
-    <make-checksums file="${dist.dir}/lucene-${version}.zip"/>
-  </target>
-
-  <!-- ================================================================== -->
-  <!-- packages the distribution with tar-gzip                            -->
-  <!-- ================================================================== -->
-  <!--                                                                    -->
-  <!-- ================================================================== -->
-
-  <!-- TODO: fix this stuff to not be a duplicate of the zip logic above! -->
-  <target name="package-tgz" depends="package"
-    description="--> Generates the lucene distribution as .tgz">
-
-    <delete file="${dist.dir}/lucene-${version}.tgz"/>
-    <tar tarfile="${dist.dir}/lucene-${version}.tgz"
-      longfile="gnu" compression="gzip">
-      <tarfileset prefix="lucene-${version}" dir=".">
-        <patternset refid="binary.root.dist.patterns"/>
-      </tarfileset>
-      <tarfileset prefix="lucene-${version}" dir="${build.dir}">
-        <patternset refid="binary.build.dist.patterns"/>
-      </tarfileset>
-      <tarfileset prefix="lucene-${version}" dir="${build.dir}" includes="**/*.sh,**/*.bat" filemode="755"/>
-    </tar>
-    <make-checksums file="${dist.dir}/lucene-${version}.tgz"/>
-  </target>
-
-  <!-- ================================================================== -->
-  <!-- packages the distribution with zip and tar-gzip                    -->
-  <!-- ================================================================== -->
-  <!--                                                                    -->
-  <!-- ================================================================== -->
-  <target name="package-all-binary" depends="package-zip, package-tgz"
-    description="--> Generates the .tgz and .zip distributions"/>
-
-  <!-- ================================================================== -->
-  <!-- same as package-all. it is just here for compatibility.            -->
-  <!-- ================================================================== -->
-  <!--                                                                    -->
-  <!-- ================================================================== -->
-  <target name="dist" depends="package-all-binary"/>
-
-  <!-- ================================================================== -->
-  <!-- S O U R C E  D I S T R I B U T I O N                               -->
-  <!-- ================================================================== -->
-    <target name="init-dist" >
-
-        <!-- Package is not called first if packaging src standalone, so the dist.dir may not exist -->
-        <mkdir dir="${build.dir}"/>
-        <mkdir dir="${dist.dir}"/>
-        <mkdir dir="${maven.dist.dir}"/>
-    </target>
-
-  <!-- ================================================================== -->
-  <!-- Packages the sources with tar-gzip               -->
-  <!-- ================================================================== -->
-  <target name="package-tgz-src" depends="init-dist"
-          description="--> Generates the Lucene source distribution as .tgz">
-    <property name="source.package.file"
-              location="${dist.dir}/lucene-${version}-src.tgz"/>
-    <delete file="${source.package.file}"/>
-    <export-source source.dir="."/>
-
-    <!-- Exclude javadoc package-list files under licenses incompatible with the ASL -->
-    <delete dir="${src.export.dir}/tools/javadoc/java8"/>
-
-    <!-- because we only package the "lucene/" folder, we have to adjust dir to work on: -->
-    <property name="local.src.export.dir" location="${src.export.dir}/lucene"/>
-    
-    <build-changes changes.src.file="${local.src.export.dir}/CHANGES.txt"
-                   changes.target.dir="${local.src.export.dir}/docs/changes"
-                   changes.product="lucene"/>
-    <tar tarfile="${source.package.file}" compression="gzip" longfile="gnu">
-      <tarfileset prefix="lucene-${version}" dir="${local.src.export.dir}"/>
-    </tar>
-    <make-checksums file="${source.package.file}"/>
-  </target>
-
-
-  <!-- ================================================================== -->
-  <!-- Packages the sources from local working copy with tar-gzip     -->
-  <!-- ================================================================== -->
-  <target name="package-local-src-tgz" depends="init-dist"
-    description="--> Packages the Lucene source from the local working copy">
-    <mkdir dir="${common.dir}/build"/>
-    <property name="source.package.file"
-              value="${common.dir}/build/lucene-${version}-src.tgz"/>
-    <delete file="${source.package.file}"/>
-    <tar tarfile="${source.package.file}" compression="gzip" longfile="gnu">
-      <tarfileset prefix="lucene-${version}" dir=".">
-        <patternset refid="lucene.local.src.package.patterns"/>
-      </tarfileset>
-    </tar>
-  </target>
-
-  <!-- ================================================================== -->
-  <!-- same as package-tgz-src. it is just here for compatibility.        -->
-  <!-- ================================================================== -->
-  <target name="dist-src" depends="package-tgz-src"/>
-
-  <target name="dist-all" depends="dist, dist-src, -dist-changes"/>
-
-  <!-- copy changes/ to the release folder -->
-  <target name="-dist-changes">
-   <copy todir="${dist.dir}/changes">
-     <fileset dir="${build.dir}/docs/changes"/>
-   </copy>
-  </target>
-
-  <target name="prepare-release-no-sign" depends="clean, dist-all, generate-maven-artifacts"/>
-  <target name="prepare-release" depends="prepare-release-no-sign, sign-artifacts"/>
-
-  <target name="-dist-maven" depends="install-maven-tasks">
-    <sequential>
-      <m2-deploy pom.xml="${filtered.pom.templates.dir}/pom.xml"/>        <!-- Lucene/Solr grandparent POM -->
-      <m2-deploy pom.xml="${filtered.pom.templates.dir}/lucene/pom.xml"/> <!-- Lucene parent POM -->
-      <subant target="-dist-maven" failonerror="true" inheritall="false">
-        <propertyset refid="uptodate.and.compiled.properties"/>
-        <fileset dir="${common.dir}/core" includes="build.xml"/>
-        <fileset dir="${common.dir}/test-framework" includes="build.xml"/>
-      </subant>
-      <modules-crawl target="-dist-maven"/>
-    </sequential>
-  </target>
-
-  <target name="-install-to-maven-local-repo" depends="install-maven-tasks">
-    <sequential>
-      <m2-install pom.xml="${filtered.pom.templates.dir}/pom.xml"/>        <!-- Lucene/Solr grandparent POM -->
-      <m2-install pom.xml="${filtered.pom.templates.dir}/lucene/pom.xml"/> <!-- Lucene parent POM -->
-      <subant target="-install-to-maven-local-repo" failonerror="true" inheritall="false">
-        <propertyset refid="uptodate.and.compiled.properties"/>
-        <fileset dir="${common.dir}/core" includes="build.xml"/>
-        <fileset dir="${common.dir}/test-framework" includes="build.xml"/>
-      </subant>
-      <modules-crawl target="-install-to-maven-local-repo"/>
-    </sequential>
-  </target>
-
-  <target name="generate-maven-artifacts" depends="-unpack-lucene-tgz">
-    <ant dir=".." target="resolve" inheritall="false"/>
-    <antcall target="-filter-pom-templates" inheritall="false"/>
-    <antcall target="-dist-maven" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </antcall>
-  </target>
-  
-  <target name="-validate-maven-dependencies" depends="compile-tools, install-maven-tasks, load-custom-tasks">
-    <sequential>
-      <subant target="-validate-maven-dependencies" failonerror="true" inheritall="false">
-        <propertyset refid="uptodate.and.compiled.properties"/>
-        <fileset dir="${common.dir}/core" includes="build.xml"/>
-        <fileset dir="${common.dir}/test-framework" includes="build.xml"/>
-      </subant>
-      
-      <modules-crawl target="-validate-maven-dependencies"/>
-    </sequential>
-  </target>
-  
-  <!-- ================================================================== -->
-  <!-- support for signing the artifacts using gpg                        -->
-  <!-- ================================================================== -->
-  <target name="sign-artifacts">
-    <sign-artifacts-macro artifacts.dir="${dist.dir}"/>
-  </target>
-
-  <target name="build-modules" depends="compile-test"
-          description="Builds all additional modules and their tests">
-    <modules-crawl target="build-artifacts-and-tests"/>
-  </target>
-
-  <target name="compile-test" description="Builds core, codecs, test-framework, and modules tests">
-    <sequential>
-      <ant dir="core" target="compile-test" inheritall="false">
-        <propertyset refid="uptodate.and.compiled.properties"/>
-      </ant>
-      <ant dir="test-framework" target="compile-test" inheritall="false">
-        <propertyset refid="uptodate.and.compiled.properties"/>
-      </ant>
-      <modules-crawl target="compile-test"/>
-    </sequential>
-  </target>
-
-  <target name="test-test-framework">
-      <ant dir="test-framework" target="test" inheritall="false">
-        <propertyset refid="uptodate.and.compiled.properties"/>
-      </ant>
-  </target>
-  
-  <target name="test-modules">
-    <modules-crawl target="test"/>
-  </target>
-
-  <target name="changes-to-html">
-    <build-changes changes.product="lucene"/>
-  </target>
-
-  <target name="pitest-modules" depends="compile-test">
-    <modules-crawl target="pitest" failonerror="false"/>
-  </target>
-
-  <target name="jacoco" description="Generates JaCoCo code coverage reports" depends="-jacoco-install">
-    <!-- run jacoco for each module -->
-    <ant dir="${common.dir}/core" target="jacoco" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <ant dir="${common.dir}/test-framework" target="jacoco" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <modules-crawl target="jacoco"/>
-
-    <!-- produce aggregate report -->
-    <property name="jacoco.output.dir" location="${jacoco.report.dir}/lucene-all"/>
-    <!-- try to clean output dir to prevent any confusion -->
-    <delete dir="${jacoco.output.dir}" failonerror="false"/>
-    <mkdir dir="${jacoco.output.dir}"/>
-
-    <jacoco:report>
-      <executiondata>
-        <fileset dir="${common.dir}/build" includes="**/jacoco.db"/>
-      </executiondata>
-      <structure name="${Name} aggregate JaCoCo coverage report">
-        <classfiles>
-          <fileset dir="${common.dir}/build">
-             <include name="**/classes/java/**/*.class"/>
-             <exclude name="tools/**"/>
-          </fileset>
-        </classfiles>
-        <!-- TODO: trying to specify source files could maybe work, but would
-             double the size of the reports -->
-      </structure>
-      <html destdir="${jacoco.output.dir}" footer="Copyright ${year} Apache Software Foundation.  All Rights Reserved."/>
-    </jacoco:report>
-  </target>
-
-  <!--
-   Committer helpers
-   -->
-
-  <property name="patch.file" value="${basedir}/../patches/${patch.name}"/>
-  <!-- Apply a patch.  Assumes  patch can be applied in the basedir.
-  -Dpatch.name assumes the patch is located in ${basedir}/../patches/${patch.name}
-  -Dpatch.file means the patch can be located anywhere on the file system
-  -->
-  <target name="apply-patch" depends="clean" description="Apply a patch file.  Set -Dpatch.file, or -Dpatch.name when the patch is in the directory ../patches/">
-    <patch patchfile="${patch.file}" strip="0"/>
-  </target>
-
-  <target name="jar-test-framework">
-    <ant dir="${common.dir}/test-framework" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-  </target>
-
-  <!-- Override common-build.xml definition to check for the jar already being up-to-date -->
-  <target name="jar-core" depends="check-lucene-core-uptodate,compile-lucene-core" unless="lucene-core.uptodate">
-    <ant dir="${common.dir}/core" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="core.compiled" value="true"/>
-    <property name="lucene-core.uptodate" value="true"/>
-  </target>
-
-  <target name="jar" depends="jar-core,jar-test-framework"
-          description="Jars core, codecs, test-framework, and all modules">
-    <modules-crawl target="jar-core"/>
-  </target>
-
-  <target name="jar-src" description="create source jars for all modules">
-    <ant dir="${common.dir}/core" target="jar-src" inheritAll="false" />
-    <ant dir="${common.dir}/test-framework" target="jar-src" inheritAll="false" />
-    <modules-crawl target="jar-src"/>
-  </target>
-
-  <target name="get-jenkins-line-docs" unless="enwiki.exists">
-    <sequential>
-      <!-- TODO: can get .lzma instead (it's ~17% smaller) but there's no builtin ant support...? -->
-      <get src="http://home.apache.org/~mikemccand/enwiki.random.lines.txt.bz2"
-           dest="enwiki.random.lines.txt.bz2"/>
-      <bunzip2 src="enwiki.random.lines.txt.bz2" dest="enwiki.random.lines.txt"/>
-    </sequential>
-  </target>
-
-  <target name="jar-checksums" depends="resolve">
-    <jar-checksum-macro srcdir="${common.dir}" dstdir="${common.dir}/licenses"/>
-  </target>
-
-  <target name="regenerate">
-    <subant target="regenerate" failonerror="true" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-      <fileset dir="core" includes="build.xml"/>
-      <fileset dir="test-framework" includes="build.xml"/>
-    </subant>
-    <modules-crawl target="regenerate"/>
-  </target>
-
-  <target name="-append-module-dependencies-properties">
-    <sequential>
-      <ant dir="core" target="common.-append-module-dependencies-properties" inheritall="false"/>
-      <ant dir="test-framework" target="common.-append-module-dependencies-properties" inheritall="false"/>
-      <modules-crawl target="-append-module-dependencies-properties"/>
-    </sequential>
-  </target>
-</project>
diff --git a/lucene/classification/build.xml b/lucene/classification/build.xml
deleted file mode 100644
index 43bcb4b..0000000
--- a/lucene/classification/build.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="classification" default="default">
-  <description>
-    Classification module for Lucene
-  </description>
-
-  <import file="../module-build.xml"/>
-
-  <path id="classpath">
-    <path refid="base.classpath"/>
-    <pathelement path="${queries.jar}"/>
-    <pathelement path="${grouping.jar}"/>
-    <pathelement path="${analyzers-common.jar}"/>
-  </path>
-
-  <path id="test.classpath">
-    <pathelement path="${analyzers-common.jar}"/>
-    <pathelement location="${codecs.jar}"/>
-    <path refid="test.base.classpath"/>
-  </path>
-
-  <target name="compile-core" depends="jar-grouping,jar-queries,jar-analyzers-common,common.compile-core" />
-
-  <target name="jar-core" depends="common.jar-core" />
-
-  <target name="javadocs" depends="javadocs-grouping,compile-core,check-javadocs-uptodate"
-          unless="javadocs-uptodate-${name}">
-    <invoke-module-javadoc>
-      <links>
-        <link href="../queries"/>
-        <link href="../analyzers-common"/>
-        <link href="../grouping"/>
-      </links>
-    </invoke-module-javadoc>
-  </target>
-
-</project>
diff --git a/lucene/classification/ivy.xml b/lucene/classification/ivy.xml
deleted file mode 100644
index 036c217..0000000
--- a/lucene/classification/ivy.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="classification"/>
-</ivy-module>
diff --git a/lucene/codecs/build.xml b/lucene/codecs/build.xml
deleted file mode 100644
index c50af6c..0000000
--- a/lucene/codecs/build.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-
-<project name="codecs" default="default">
-  <description>
-    Lucene codecs and postings formats.
-  </description>
-
-  <import file="../module-build.xml"/>
-
-  <target name="-dist-maven" depends="-dist-maven-src-java"/>
-
-  <target name="-install-to-maven-local-repo" depends="-install-src-java-to-maven-local-repo"/>
-</project>
diff --git a/lucene/codecs/ivy.xml b/lucene/codecs/ivy.xml
deleted file mode 100644
index f966fd5..0000000
--- a/lucene/codecs/ivy.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="codecs"/>
-</ivy-module>
diff --git a/lucene/core/build.xml b/lucene/core/build.xml
deleted file mode 100644
index 5fa7512..0000000
--- a/lucene/core/build.xml
+++ /dev/null
@@ -1,235 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="core" default="default">
-  <description>Lucene core library</description>
-
-  <property name="build.dir" location="../build/core"/>
-
-  <!-- lucene core can use the minimal JDK profile -->
-  <property name="javac.profile.args" value="-profile compact1"/>
-  <import file="../common-build.xml"/>
-
-  <property name="moman.commit-hash" value="497c90e34e412b6494db6dabf0d95db8034bd325" />
-  <property name="moman.url" value="https://github.com/jpbarrette/moman/archive/${moman.commit-hash}.zip" />
-
-  <path id="classpath"/>
-  
-  <path id="test.classpath">
-    <pathelement location="${common.dir}/build/codecs/classes/java"/>
-    <pathelement location="${common.dir}/build/test-framework/classes/java"/>
-    <path refid="junit-path"/>
-    <pathelement location="${build.dir}/classes/java"/>
-    <pathelement location="${build.dir}/classes/test"/>
-  </path>
-
-  <path id="junit.classpath">
-    <path refid="test.classpath"/>
-  </path>
-
-  <target name="test-core" depends="common.test"/>
-
-  <target name="javadocs-core" depends="javadocs"/>
-  <target name="javadocs" description="Generate javadoc for core classes" 
-          depends="check-javadocs-uptodate" unless="javadocs-uptodate-${name}">
-     <sequential>
-      <mkdir dir="${javadoc.dir}/core"/>
-      <invoke-javadoc destdir="${javadoc.dir}/core" title="${Name} ${version} core API">
-        <sources>
-          <packageset dir="${src.dir}"/>
-          <link href=""/>
-        </sources>
-      </invoke-javadoc>
-      <mkdir dir="${build.dir}"/>
-     <jarify basedir="${javadoc.dir}/core" destfile="${build.dir}/${final.name}-javadoc.jar"/>
-    </sequential>
-  </target>
-
-  <target name="-dist-maven" depends="-dist-maven-src-java"/>
-
-  <target name="-install-to-maven-local-repo" depends="-install-src-java-to-maven-local-repo"/>
-
-  <macrodef name="createLevAutomaton">
-      <attribute name="n"/>
-      <sequential>
-      <exec dir="src/java/org/apache/lucene/util/automaton"
-            executable="${python3.exe}" failonerror="true">
-        <!-- Tell Python not to write any bytecode cache into the filesystem: -->
-        <arg value="-B"/>
-        <arg value="createLevAutomata.py"/>
-        <arg value="@{n}"/>
-        <arg value="True"/>
-        <!-- Hack while transitioning to Gradle build in 9.0 -->
-        <arg value="../../../../../../../../build/core/moman/finenight/python"/>
-      </exec>
-      <exec dir="src/java/org/apache/lucene/util/automaton"
-            executable="${python3.exe}" failonerror="true">
-        <!-- Tell Python not to write any bytecode cache into the filesystem: -->
-        <arg value="-B"/>
-        <arg value="createLevAutomata.py"/>
-        <arg value="@{n}"/>
-        <arg value="False"/>
-        <!-- Hack while transitioning to Gradle build in 9.0 -->
-        <arg value="../../../../../../../../build/core/moman/finenight/python"/>
-      </exec>
-      <fixcrlf srcdir="src/java/org/apache/lucene/util/automaton" includes="*ParametricDescription.java" encoding="UTF-8"/>
-    </sequential>
-  </macrodef>
-
-  <target name="createPackedIntSources">
-    <exec dir="src/java/org/apache/lucene/util/packed"
-          executable="${python3.exe}" failonerror="true">
-      <!-- Tell Python not to write any bytecode cache into the filesystem: -->
-      <arg value="-B"/>
-      <arg value="gen_BulkOperation.py"/>
-    </exec>
-    <exec dir="src/java/org/apache/lucene/util/packed"
-          executable="${python3.exe}" failonerror="true">
-      <!-- Tell Python not to write any bytecode cache into the filesystem: -->
-      <arg value="-B"/>
-      <arg value="gen_Packed64SingleBlock.py"/>
-    </exec>
-    <fixcrlf srcdir="src/java/org/apache/lucene/util/packed" includes="BulkOperation*.java,Packed64SingleBlock.java" encoding="UTF-8"/>
-  </target>
-
-  <target name="createLevAutomata" depends="check-moman,download-moman">
-    <createLevAutomaton n="1"/>
-    <createLevAutomaton n="2"/>
-  </target>
-  
-  <target name="check-moman">
-    <available file="${build.dir}/moman" property="moman.downloaded"/>
-  </target>
-
-  <target name="download-moman" unless="moman.downloaded">
-    <mkdir dir="${build.dir}/moman"/>
-    <get src="${moman.url}" dest="${build.dir}/moman.zip"/>
-    <unzip dest="${build.dir}/moman" src="${build.dir}/moman.zip">
-      <cutdirsmapper dirs="1"/>
-    </unzip>
-    <delete file="${build.dir}/moman.zip"/>
-  </target>
-
-  <target name="regenerate" depends="createLevAutomata,createPackedIntSources,jflex"/>
-  
-  <macrodef name="startLockStressTestClient">
-    <attribute name="clientId"/>
-    <attribute name="lockFactoryImpl"/>
-    <attribute name="lockFactoryDir"/>
-    <sequential>
-      <local name="lockverifyserver.port"/>
-      <groovy><![CDATA[
-        String port;
-        while ((port = System.getProperty("lockverifyserver.port")) == null) {
-          Thread.sleep(10L);
-        }
-        properties["lockverifyserver.port"] = port;
-      ]]></groovy>
-      <java taskname="lockStressTest@{clientId}" fork="true" classpathref="test-lock.classpath" classname="org.apache.lucene.store.LockStressTest" failOnError="true"> 
-        <arg value="@{clientId}"/>
-        <arg value="${lockverifyserver.host}"/>
-        <arg value="${lockverifyserver.port}"/>
-        <arg value="@{lockFactoryImpl}"/>
-        <arg value="@{lockFactoryDir}"/>
-        <arg value="${lockverify.delay}"/>
-        <arg value="${lockverify.count}"/>
-      </java>
-    </sequential>
-  </macrodef>
-  
-  <macrodef name="testLockFactory">
-    <attribute name="lockFactoryImpl"/>
-    <attribute name="lockFactoryDir"/>
-    <sequential>
-      <echo taskname="testLockFactory" message="Testing @{lockFactoryImpl}..."/>
-      <mkdir dir="@{lockFactoryDir}"/>
-      <parallel threadCount="3" failonany="false">
-        <sequential>
-          <!-- the server runs in-process, so we can wait for the sysproperty -->
-          <java taskname="lockVerifyServer" fork="false" classpathref="test-lock.classpath" classname="org.apache.lucene.store.LockVerifyServer" failOnError="true">
-            <arg value="${lockverifyserver.host}"/>
-            <arg value="2"/>
-          </java>
-        </sequential>
-        <sequential>
-          <startLockStressTestClient clientId="1" lockFactoryImpl="@{lockFactoryImpl}" lockFactoryDir="@{lockFactoryDir}" />
-        </sequential>
-        <sequential>
-          <startLockStressTestClient clientId="2" lockFactoryImpl="@{lockFactoryImpl}" lockFactoryDir="@{lockFactoryDir}" />
-        </sequential>
-      </parallel>
-    </sequential>
-  </macrodef>
-  
-  <condition property="-ignore-test-lock-factory">
-    <or>
-      <!-- We ignore our ant-based lock factory test, if user applies test filtering: -->
-      <isset property="tests.class" />
-      <isset property="tests.method" />
-      <!-- Clover seems to deadlock if running instrumented code inside the Ant JVM: -->
-      <isset property="run.clover" />
-    </or>
-  </condition>
-  
-  <target name="test-lock-factory" depends="resolve-groovy,compile-core" unless="-ignore-test-lock-factory"
-    description="Run LockStressTest with multiple JVMs">
-    <property name="lockverifyserver.host" value="127.0.0.1"/>
-    <property name="lockverify.delay" value="1"/>
-    <groovy taskname="lockVerifySetup"><![CDATA[
-      System.clearProperty("lockverifyserver.port"); // make sure it is undefined
-      
-      if (!properties["lockverify.count"]) {
-        int count = Boolean.parseBoolean(properties["tests.nightly"]) ?
-          30000 : 500;
-        count *= Integer.parseInt(properties["tests.multiplier"]);
-        properties["lockverify.count"] = count;
-      }
-      
-      task.log("Configuration properties:");
-      ["lockverify.delay", "lockverify.count"].each {
-        k -> task.log(" " + k + "=" + properties[k]);
-      }
-    ]]></groovy>
-    <path id="test-lock.classpath">
-      <path refid="classpath"/>
-      <pathelement location="${build.dir}/classes/java"/>
-    </path>
-    <testLockFactory lockFactoryImpl="org.apache.lucene.store.NativeFSLockFactory" lockFactoryDir="${build.dir}/lockfactorytest/native" />
-    <testLockFactory lockFactoryImpl="org.apache.lucene.store.SimpleFSLockFactory" lockFactoryDir="${build.dir}/lockfactorytest/simple" />
-  </target>
-  
-  <target name="test" depends="common.test, test-lock-factory"/>
-
-  <target name="clean-jflex">
-    <delete>
-      <fileset dir="src/java/org/apache/lucene/analysis/standard" includes="**/*.java">
-        <containsregexp expression="generated.*by.*JFlex"/>
-      </fileset>
-    </delete>
-  </target>
-
-  <target name="jflex" depends="-install-jflex,clean-jflex,-jflex-StandardAnalyzer"/>
-  
-  <target name="-jflex-StandardAnalyzer" depends="init,-install-jflex">
-    <run-jflex-and-disable-buffer-expansion 
-        dir="src/java/org/apache/lucene/analysis/standard" name="StandardTokenizerImpl"/>
-  </target>
-
-
-</project>
diff --git a/lucene/core/ivy.xml b/lucene/core/ivy.xml
deleted file mode 100644
index bbca9f9..0000000
--- a/lucene/core/ivy.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="core"/>
-</ivy-module>
diff --git a/lucene/default-nested-ivy-settings.xml b/lucene/default-nested-ivy-settings.xml
deleted file mode 100644
index 1b1603f..0000000
--- a/lucene/default-nested-ivy-settings.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.
--->
-<ivysettings>
-  <!-- This file is included by default by top-level-ivy-settings.xml,
-       which loads ivy-versions.properties as Ivy variables.          -->
-
-  <settings defaultResolver="default"/>
-
-  <property name="local-maven2-dir" value="${user.home}/.m2/repository/" />
-
-  <include url="${ivy.default.settings.dir}/ivysettings-public.xml"/>
-  <include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/>
-  <include url="${ivy.default.settings.dir}/ivysettings-local.xml"/>
-  <include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/>
-
-  <caches lockStrategy="${ivy.lock-strategy}" resolutionCacheDir="${ivy.resolution-cache.dir}" />
-
-  <resolvers>
-    <ibiblio name="sonatype-releases" root="https://oss.sonatype.org/content/repositories/releases" m2compatible="true" />
-    <ibiblio name="maven.restlet.com" root="https://maven.restlet.com" m2compatible="true" />
-    <ibiblio name="releases.cloudera.com" root="https://repository.cloudera.com/artifactory/libs-release-local" m2compatible="true" />
-
-    <filesystem name="local-maven-2" m2compatible="true" local="true">
-      <artifact
-          pattern="${local-maven2-dir}/[organisation]/[module]/[revision]/[module]-[revision](-[classifier]).[ext]" />
-      <ivy
-          pattern="${local-maven2-dir}/[organisation]/[module]/[revision]/[module]-[revision].pom" />
-    </filesystem>
-
-    <chain name="default" returnFirst="true" checkmodified="true" changingPattern=".*SNAPSHOT">
-      <resolver ref="local"/>
-      <!-- <resolver ref="local-maven-2" /> -->
-      <resolver ref="main"/>
-      <resolver ref="maven.restlet.com" />
-      <resolver ref="sonatype-releases" />
-      <resolver ref="releases.cloudera.com"/>
-    </chain>
-  </resolvers>
-
-</ivysettings>
diff --git a/lucene/demo/build.xml b/lucene/demo/build.xml
deleted file mode 100644
index d5e50ad..0000000
--- a/lucene/demo/build.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="demo" default="default" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
-
-  <description>
-    Simple example code
-  </description>
-
-  <property name="demo.name" value="lucene-demos-${version}"/>
-
-  <import file="../module-build.xml"/>
-
-  <target name="init" depends="module-build.init,jar-lucene-core"/>
-  
-  <path id="classpath">
-   <pathelement path="${analyzers-common.jar}"/>
-   <pathelement path="${queryparser.jar}"/>
-   <pathelement path="${lucene-core.jar}"/>
-   <pathelement path="${queries.jar}"/>
-   <pathelement path="${facet.jar}"/>
-   <pathelement path="${expressions.jar}"/>
-   <fileset dir="../expressions/lib"/>
-  </path>
-
-  <target name="javadocs" depends="javadocs-analyzers-common,javadocs-queryparser,javadocs-facet,javadocs-expressions,compile-core,check-javadocs-uptodate"
-          unless="javadocs-uptodate-${name}">
-    <!-- we link the example source in the javadocs, as it's ref'ed elsewhere -->
-    <invoke-module-javadoc linksource="yes">
-      <links>
-        <link href="../analyzers-common"/>
-        <link href="../queryparser"/>
-        <link href="../queries"/>
-        <link href="../facet"/>
-        <link href="../expressions"/>
-      </links>
-    </invoke-module-javadoc>
-  </target>
-
-  <!-- we don't check for sysout in demo, because the demo is there to use sysout :-) -->
-  <target name="-check-forbidden-sysout"/>
-
-  <target name="compile-core" depends="jar-analyzers-common,jar-queryparser,jar-queries,jar-facet,jar-expressions,common.compile-core" />
-
-</project>
diff --git a/lucene/demo/ivy.xml b/lucene/demo/ivy.xml
deleted file mode 100644
index 69076d1..0000000
--- a/lucene/demo/ivy.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="demo"/>
-</ivy-module>
diff --git a/lucene/expressions/build.xml b/lucene/expressions/build.xml
deleted file mode 100644
index 61ae64f..0000000
--- a/lucene/expressions/build.xml
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0"?>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-<project name="expressions" default="default">
-
-  <description>
-    Dynamically computed values to sort/facet/search on based on a pluggable grammar.
-  </description>
-
-  <import file="../module-build.xml"/>
-
-  <path id="classpath">
-    <path refid="base.classpath"/>
-    <fileset dir="lib"/>
-  </path>
-
-  <path id="test.classpath">
-    <path refid="test.base.classpath"/>
-    <fileset dir="lib"/>
-    <pathelement path="src/test-files"/>
-  </path>
-
-  <target name="regenerate" depends="run-antlr"/>
-
-  <target name="resolve-antlr" xmlns:ivy="antlib:org.apache.ivy.ant">
-    <ivy:cachepath organisation="org.antlr" module="antlr4" revision="4.5.1-1"
-                  inline="true" conf="default" type="jar" pathid="antlr.classpath"/>
-  </target>
-
-  <target name="run-antlr" depends="resolve-antlr">
-    <regen-grammar package="js" grammar="Javascript"/>
-  </target>
-  
-  <macrodef name="replace-value">
-    <attribute name="value" />
-    <attribute name="property" />
-    <attribute name="from" />
-    <attribute name="to" />
-    <sequential>
-      <loadresource property="@{property}">
-        <string value="@{value}"/>
-        <filterchain>
-          <tokenfilter>
-            <filetokenizer/>
-            <replacestring from="@{from}" to="@{to}"/>
-          </tokenfilter>
-        </filterchain>
-      </loadresource>
-    </sequential>
-  </macrodef>
-
-  <macrodef name="regen-grammar">
-    <attribute name="package" />
-    <attribute name="grammar" />
-    <sequential>
-      <local name="grammar.path"/>
-      <patternset id="grammar.@{grammar}.patternset">
-        <include name="@{grammar}Lexer.java" />
-        <include name="@{grammar}Parser.java" />
-        <include name="@{grammar}Visitor.java" />
-        <include name="@{grammar}BaseVisitor.java" />
-      </patternset>
-      <property name="grammar.path" location="src/java/org/apache/lucene/expressions/@{package}"/>
-      <!-- delete parser and lexer so files will be generated -->
-      <delete dir="${grammar.path}">
-        <patternset refid="grammar.@{grammar}.patternset"/>
-      </delete>
-      <!-- invoke ANTLR4 -->
-      <java classname="org.antlr.v4.Tool" fork="true" failonerror="true" classpathref="antlr.classpath" taskname="antlr">
-        <sysproperty key="file.encoding" value="UTF-8"/>
-        <sysproperty key="user.language" value="en"/>
-        <sysproperty key="user.country" value="US"/>
-        <sysproperty key="user.variant" value=""/>
-        <arg value="-package"/>
-        <arg value="org.apache.lucene.expressions.@{package}"/>
-        <arg value="-no-listener"/>
-        <arg value="-visitor"/>
-        <arg value="-o"/>
-        <arg path="${grammar.path}"/>
-        <arg path="${grammar.path}/@{grammar}.g4"/>
-      </java>
-      <!-- fileset with files to edit -->
-      <fileset id="grammar.fileset" dir="${grammar.path}">
-        <patternset refid="grammar.@{grammar}.patternset"/>
-      </fileset>
-      <!-- remove files that are not needed to compile or at runtime -->
-      <delete dir="${grammar.path}" includes="@{grammar}*.tokens"/>
-      <!-- make the generated classes package private -->
-      <replaceregexp match="public ((interface|class) \Q@{grammar}\E\w+)" replace="\1" encoding="UTF-8">
-        <fileset refid="grammar.fileset"/>
-      </replaceregexp>
-      <!-- nuke timestamps/filenames in generated files -->
-      <replaceregexp match="\Q// Generated from \E.*" replace="\/\/ ANTLR GENERATED CODE: DO NOT EDIT" encoding="UTF-8">
-        <fileset refid="grammar.fileset"/>
-      </replaceregexp>
-      <!-- remove tabs in antlr generated files -->
-      <replaceregexp match="\t" flags="g" replace="  " encoding="UTF-8">
-        <fileset refid="grammar.fileset"/>
-      </replaceregexp>
-      <!-- fix line endings -->
-      <fixcrlf srcdir="${grammar.path}">
-        <patternset refid="grammar.@{grammar}.patternset"/>
-      </fixcrlf>
-    </sequential>
-  </macrodef>
-</project>
diff --git a/lucene/expressions/ivy.xml b/lucene/expressions/ivy.xml
deleted file mode 100644
index 6065522..0000000
--- a/lucene/expressions/ivy.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="expressions"/>
-  <configurations defaultconfmapping="compile->master">
-    <conf name="compile" transitive="false"/>
-  </configurations>
-  <dependencies>
-    <dependency org="org.antlr" name="antlr4-runtime" rev="${/org.antlr/antlr4-runtime}" conf="compile"/>
-    <dependency org="org.ow2.asm" name="asm" rev="${/org.ow2.asm/asm}" conf="compile"/>
-    <dependency org="org.ow2.asm" name="asm-commons" rev="${/org.ow2.asm/asm-commons}" conf="compile"/>
-    <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/>
-  </dependencies>
-</ivy-module>
diff --git a/lucene/facet/build.xml b/lucene/facet/build.xml
deleted file mode 100644
index 2fc2f9a..0000000
--- a/lucene/facet/build.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="facet" default="default">
-
-  <description>
-    Faceted indexing and search capabilities
-  </description>
-
-  <import file="../module-build.xml"/>
-
-  <path id="classpath">
-    <path refid="base.classpath"/>
-    <fileset dir="lib"/>
-  </path>
-
-  <path id="test.classpath">
-    <pathelement path="${queries.jar}"/>
-    <path refid="test.base.classpath"/>
-  </path>
-
-  <target name="compile-core" depends="jar-queries,common.compile-core"/>
-
-  <target name="run-encoding-benchmark" depends="compile-test">
-    <java classname="org.apache.lucene.util.encoding.EncodingSpeed" fork="true" failonerror="true">
-      <classpath refid="test.classpath" />
-      <classpath path="${build.dir}/classes/test" />
-    </java>
-  </target>
-
-</project>
diff --git a/lucene/facet/ivy.xml b/lucene/facet/ivy.xml
deleted file mode 100644
index 249c78e..0000000
--- a/lucene/facet/ivy.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="facet"/>
-  <configurations defaultconfmapping="compile->master">
-    <conf name="compile" transitive="false"/>
-  </configurations>
-  <dependencies>
-    <dependency org="com.carrotsearch" name="hppc" rev="${/com.carrotsearch/hppc}" conf="compile"/>
-  </dependencies>
-</ivy-module>
diff --git a/lucene/grouping/build.xml b/lucene/grouping/build.xml
deleted file mode 100644
index 5fb1fd1..0000000
--- a/lucene/grouping/build.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="grouping" default="default">
-  
-    <description>
-       Collectors for grouping search results.
-    </description>
-
-    <import file="../module-build.xml"/>
-
-    <path id="test.classpath">
-      <path refid="test.base.classpath" />
-      <pathelement path="${queries.jar}" />
-    </path>
-
-    <path id="classpath">
-      <pathelement path="${queries.jar}" />
-      <path refid="base.classpath"/>
-    </path>
-
-    <target name="init" depends="module-build.init,jar-queries"/>
-
-    <target name="javadocs" depends="javadocs-queries,compile-core,check-javadocs-uptodate"
-            unless="javadocs-uptodate-${name}">
-      <invoke-module-javadoc>
-        <links>
-          <link href="../queries"/>
-        </links>
-      </invoke-module-javadoc>
-    </target>
-
-</project>
diff --git a/lucene/grouping/ivy.xml b/lucene/grouping/ivy.xml
deleted file mode 100644
index d7e4eb3..0000000
--- a/lucene/grouping/ivy.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="grouping"/>
-</ivy-module>
diff --git a/lucene/highlighter/ivy.xml b/lucene/highlighter/ivy.xml
deleted file mode 100644
index 262fa53..0000000
--- a/lucene/highlighter/ivy.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="highlighter"/>
-</ivy-module>
diff --git a/lucene/ivy-ignore-conflicts.properties b/lucene/ivy-ignore-conflicts.properties
deleted file mode 100644
index df3a2e5..0000000
--- a/lucene/ivy-ignore-conflicts.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# The /org/name keys in this file must be kept lexically sorted.
-# Blank lines, comment lines, and keys that aren't in /org/name format are ignored
-# when the lexical sort check is performed by the ant check-lib-versions target.
-#
-# The format is:
-#
-# /org/name = <version1> [, <version2> [ ... ] ]
-#
-# where each <versionX> is an indirect dependency version to ignore (i.e., not
-# trigger a conflict) when the ant check-lib-versions target is run.
-
-/com.google.guava/guava = 16.0.1
-/org.ow2.asm/asm = 5.0_BETA
-
diff --git a/lucene/join/build.xml b/lucene/join/build.xml
deleted file mode 100644
index c411dbe..0000000
--- a/lucene/join/build.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0"?>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.
--->
-<project name="join" default="default">
-  <description>
-    Index-time and Query-time joins for normalized content
-  </description>
-
-  <import file="../module-build.xml"/>
-
-</project>
diff --git a/lucene/join/ivy.xml b/lucene/join/ivy.xml
deleted file mode 100644
index 09ae9bd..0000000
--- a/lucene/join/ivy.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="join"/>
-</ivy-module>
diff --git a/lucene/licenses/ant-1.8.2.jar.sha1 b/lucene/licenses/ant-1.8.2.jar.sha1
deleted file mode 100644
index 564db78..0000000
--- a/lucene/licenses/ant-1.8.2.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-fc33bf7cd8c5309dd7b81228e8626515ee42efd9
diff --git a/lucene/licenses/ant-LICENSE-ASL.txt b/lucene/licenses/ant-LICENSE-ASL.txt
deleted file mode 100644
index ab3182e..0000000
--- a/lucene/licenses/ant-LICENSE-ASL.txt
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- *                                 Apache License
- *                           Version 2.0, January 2004
- *                        http://www.apache.org/licenses/
- *
- *   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
- *
- *   1. Definitions.
- *
- *      "License" shall mean the terms and conditions for use, reproduction,
- *      and distribution as defined by Sections 1 through 9 of this document.
- *
- *      "Licensor" shall mean the copyright owner or entity authorized by
- *      the copyright owner that is granting the License.
- *
- *      "Legal Entity" shall mean the union of the acting entity and all
- *      other entities that control, are controlled by, or are under common
- *      control with that entity. For the purposes of this definition,
- *      "control" means (i) the power, direct or indirect, to cause the
- *      direction or management of such entity, whether by contract or
- *      otherwise, or (ii) ownership of fifty percent (50%) or more of the
- *      outstanding shares, or (iii) beneficial ownership of such entity.
- *
- *      "You" (or "Your") shall mean an individual or Legal Entity
- *      exercising permissions granted by this License.
- *
- *      "Source" form shall mean the preferred form for making modifications,
- *      including but not limited to software source code, documentation
- *      source, and configuration files.
- *
- *      "Object" form shall mean any form resulting from mechanical
- *      transformation or translation of a Source form, including but
- *      not limited to compiled object code, generated documentation,
- *      and conversions to other media types.
- *
- *      "Work" shall mean the work of authorship, whether in Source or
- *      Object form, made available under the License, as indicated by a
- *      copyright notice that is included in or attached to the work
- *      (an example is provided in the Appendix below).
- *
- *      "Derivative Works" shall mean any work, whether in Source or Object
- *      form, that is based on (or derived from) the Work and for which the
- *      editorial revisions, annotations, elaborations, or other modifications
- *      represent, as a whole, an original work of authorship. For the purposes
- *      of this License, Derivative Works shall not include works that remain
- *      separable from, or merely link (or bind by name) to the interfaces of,
- *      the Work and Derivative Works thereof.
- *
- *      "Contribution" shall mean any work of authorship, including
- *      the original version of the Work and any modifications or additions
- *      to that Work or Derivative Works thereof, that is intentionally
- *      submitted to Licensor for inclusion in the Work by the copyright owner
- *      or by an individual or Legal Entity authorized to submit on behalf of
- *      the copyright owner. For the purposes of this definition, "submitted"
- *      means any form of electronic, verbal, or written communication sent
- *      to the Licensor or its representatives, including but not limited to
- *      communication on electronic mailing lists, source code control systems,
- *      and issue tracking systems that are managed by, or on behalf of, the
- *      Licensor for the purpose of discussing and improving the Work, but
- *      excluding communication that is conspicuously marked or otherwise
- *      designated in writing by the copyright owner as "Not a Contribution."
- *
- *      "Contributor" shall mean Licensor and any individual or Legal Entity
- *      on behalf of whom a Contribution has been received by Licensor and
- *      subsequently incorporated within the Work.
- *
- *   2. Grant of Copyright License. Subject to the terms and conditions of
- *      this License, each Contributor hereby grants to You a perpetual,
- *      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- *      copyright license to reproduce, prepare Derivative Works of,
- *      publicly display, publicly perform, sublicense, and distribute the
- *      Work and such Derivative Works in Source or Object form.
- *
- *   3. Grant of Patent License. Subject to the terms and conditions of
- *      this License, each Contributor hereby grants to You a perpetual,
- *      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- *      (except as stated in this section) patent license to make, have made,
- *      use, offer to sell, sell, import, and otherwise transfer the Work,
- *      where such license applies only to those patent claims licensable
- *      by such Contributor that are necessarily infringed by their
- *      Contribution(s) alone or by combination of their Contribution(s)
- *      with the Work to which such Contribution(s) was submitted. If You
- *      institute patent litigation against any entity (including a
- *      cross-claim or counterclaim in a lawsuit) alleging that the Work
- *      or a Contribution incorporated within the Work constitutes direct
- *      or contributory patent infringement, then any patent licenses
- *      granted to You under this License for that Work shall terminate
- *      as of the date such litigation is filed.
- *
- *   4. Redistribution. You may reproduce and distribute copies of the
- *      Work or Derivative Works thereof in any medium, with or without
- *      modifications, and in Source or Object form, provided that You
- *      meet the following conditions:
- *
- *      (a) You must give any other recipients of the Work or
- *          Derivative Works a copy of this License; and
- *
- *      (b) You must cause any modified files to carry prominent notices
- *          stating that You changed the files; and
- *
- *      (c) You must retain, in the Source form of any Derivative Works
- *          that You distribute, all copyright, patent, trademark, and
- *          attribution notices from the Source form of the Work,
- *          excluding those notices that do not pertain to any part of
- *          the Derivative Works; and
- *
- *      (d) If the Work includes a "NOTICE" text file as part of its
- *          distribution, then any Derivative Works that You distribute must
- *          include a readable copy of the attribution notices contained
- *          within such NOTICE file, excluding those notices that do not
- *          pertain to any part of the Derivative Works, in at least one
- *          of the following places: within a NOTICE text file distributed
- *          as part of the Derivative Works; within the Source form or
- *          documentation, if provided along with the Derivative Works; or,
- *          within a display generated by the Derivative Works, if and
- *          wherever such third-party notices normally appear. The contents
- *          of the NOTICE file are for informational purposes only and
- *          do not modify the License. You may add Your own attribution
- *          notices within Derivative Works that You distribute, alongside
- *          or as an addendum to the NOTICE text from the Work, provided
- *          that such additional attribution notices cannot be construed
- *          as modifying the License.
- *
- *      You may add Your own copyright statement to Your modifications and
- *      may provide additional or different license terms and conditions
- *      for use, reproduction, or distribution of Your modifications, or
- *      for any such Derivative Works as a whole, provided Your use,
- *      reproduction, and distribution of the Work otherwise complies with
- *      the conditions stated in this License.
- *
- *   5. Submission of Contributions. Unless You explicitly state otherwise,
- *      any Contribution intentionally submitted for inclusion in the Work
- *      by You to the Licensor shall be under the terms and conditions of
- *      this License, without any additional terms or conditions.
- *      Notwithstanding the above, nothing herein shall supersede or modify
- *      the terms of any separate license agreement you may have executed
- *      with Licensor regarding such Contributions.
- *
- *   6. Trademarks. This License does not grant permission to use the trade
- *      names, trademarks, service marks, or product names of the Licensor,
- *      except as required for reasonable and customary use in describing the
- *      origin of the Work and reproducing the content of the NOTICE file.
- *
- *   7. Disclaimer of Warranty. Unless required by applicable law or
- *      agreed to in writing, Licensor provides the Work (and each
- *      Contributor provides its Contributions) on an "AS IS" BASIS,
- *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- *      implied, including, without limitation, any warranties or conditions
- *      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- *      PARTICULAR PURPOSE. You are solely responsible for determining the
- *      appropriateness of using or redistributing the Work and assume any
- *      risks associated with Your exercise of permissions under this License.
- *
- *   8. Limitation of Liability. In no event and under no legal theory,
- *      whether in tort (including negligence), contract, or otherwise,
- *      unless required by applicable law (such as deliberate and grossly
- *      negligent acts) or agreed to in writing, shall any Contributor be
- *      liable to You for damages, including any direct, indirect, special,
- *      incidental, or consequential damages of any character arising as a
- *      result of this License or out of the use or inability to use the
- *      Work (including but not limited to damages for loss of goodwill,
- *      work stoppage, computer failure or malfunction, or any and all
- *      other commercial damages or losses), even if such Contributor
- *      has been advised of the possibility of such damages.
- *
- *   9. Accepting Warranty or Additional Liability. While redistributing
- *      the Work or Derivative Works thereof, You may choose to offer,
- *      and charge a fee for, acceptance of support, warranty, indemnity,
- *      or other liability obligations and/or rights consistent with this
- *      License. However, in accepting such obligations, You may act only
- *      on Your own behalf and on Your sole responsibility, not on behalf
- *      of any other Contributor, and only if You agree to indemnify,
- *      defend, and hold each Contributor harmless for any liability
- *      incurred by, or claims asserted against, such Contributor by reason
- *      of your accepting any such warranty or additional liability.
- *
- *   END OF TERMS AND CONDITIONS
- *
- *   APPENDIX: How to apply the Apache License to your work.
- *
- *      To apply the Apache License to your work, attach the following
- *      boilerplate notice, with the fields enclosed by brackets "[]"
- *      replaced with your own identifying information. (Don't include
- *      the brackets!)  The text should be enclosed in the appropriate
- *      comment syntax for the file format. We also recommend that a
- *      file or class name and description of purpose be included on the
- *      same "printed page" as the copyright notice for easier
- *      identification within third-party archives.
- *
- *   Copyright [yyyy] [name of copyright owner]
- *
- *   Licensed 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.
- */
-
-W3C® SOFTWARE NOTICE AND LICENSE
-http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
-
-This work (and included software, documentation such as READMEs, or other
-related items) is being provided by the copyright holders under the following
-license. By obtaining, using and/or copying this work, you (the licensee) agree
-that you have read, understood, and will comply with the following terms and
-conditions.
-
-Permission to copy, modify, and distribute this software and its documentation,
-with or without modification, for any purpose and without fee or royalty is
-hereby granted, provided that you include the following on ALL copies of the
-software and documentation or portions thereof, including modifications:
-
-  1. The full text of this NOTICE in a location viewable to users of the
-     redistributed or derivative work. 
-  2. Any pre-existing intellectual property disclaimers, notices, or terms
-     and conditions. If none exist, the W3C Software Short Notice should be
-     included (hypertext is preferred, text is permitted) within the body
-     of any redistributed or derivative code.
-  3. Notice of any changes or modifications to the files, including the date
-     changes were made. (We recommend you provide URIs to the location from
-     which the code is derived.)
-     
-THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE
-NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT
-THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
-PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
-
-COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
-
-The name and trademarks of copyright holders may NOT be used in advertising or
-publicity pertaining to the software without specific, written prior permission.
-Title to copyright in this software and any associated documentation will at
-all times remain with copyright holders.
-
-____________________________________
-
-This formulation of W3C's notice and license became active on December 31 2002.
-This version removes the copyright ownership notice such that this license can
-be used with materials other than those owned by the W3C, reflects that ERCIM
-is now a host of the W3C, includes references to this specific dated version of
-the license, and removes the ambiguous grant of "use". Otherwise, this version
-is the same as the previous version and is written so as to preserve the Free
-Software Foundation's assessment of GPL compatibility and OSI's certification
-under the Open Source Definition. Please see our Copyright FAQ for common
-questions about using materials from our site, including specific terms and
-conditions for packages like libwww, Amaya, and Jigsaw. Other questions about
-this notice can be directed to site-policy@w3.org.
- 
-Joseph Reagle <si...@w3.org> 
-
-This license came from: http://www.megginson.com/SAX/copying.html
-  However please note future versions of SAX may be covered 
-  under http://saxproject.org/?selected=pd
-
-SAX2 is Free!
-
-I hereby abandon any property rights to SAX 2.0 (the Simple API for
-XML), and release all of the SAX 2.0 source code, compiled code, and
-documentation contained in this distribution into the Public Domain.
-SAX comes with NO WARRANTY or guarantee of fitness for any
-purpose.
-
-David Megginson, david@megginson.com
-2000-05-05
diff --git a/lucene/licenses/ant-NOTICE.txt b/lucene/licenses/ant-NOTICE.txt
deleted file mode 100644
index 4c88cc6..0000000
--- a/lucene/licenses/ant-NOTICE.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-   =========================================================================
-   ==  NOTICE file corresponding to the section 4 d of                    ==
-   ==  the Apache License, Version 2.0,                                   ==
-   ==  in this case for the Apache Ant distribution.                      ==
-   =========================================================================
-
-   Apache Ant
-   Copyright 1999-2008 The Apache Software Foundation
-
-   This product includes software developed by
-   The Apache Software Foundation (http://www.apache.org/).
-
-   This product includes also software developed by :
-     - the W3C consortium (http://www.w3c.org) ,
-     - the SAX project (http://www.saxproject.org)
-
-   The <sync> task is based on code Copyright (c) 2002, Landmark
-   Graphics Corp that has been kindly donated to the Apache Software
-   Foundation.
-
-   Portions of this software were originally based on the following:
-     - software copyright (c) 1999, IBM Corporation., http://www.ibm.com.
-     - software copyright (c) 1999, Sun Microsystems., http://www.sun.com.
-     - voluntary contributions made by Paul Eng on behalf of the 
-       Apache Software Foundation that were originally developed at iClick, Inc.,
-       software copyright (c) 1999.
diff --git a/lucene/licenses/ivy-2.4.0.jar.sha1 b/lucene/licenses/ivy-2.4.0.jar.sha1
deleted file mode 100644
index 3863b25..0000000
--- a/lucene/licenses/ivy-2.4.0.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-5abe4c24bbe992a9ac07ca563d5bd3e8d569e9ed
diff --git a/lucene/licenses/ivy-LICENSE-ASL.txt b/lucene/licenses/ivy-LICENSE-ASL.txt
deleted file mode 100644
index eb06170..0000000
--- a/lucene/licenses/ivy-LICENSE-ASL.txt
+++ /dev/null
@@ -1,258 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
... 7077 lines suppressed ...


[lucene-solr] 30/39: LUCENE-9475: remove obsolete ant-only jar sha's from Solr.

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 9f270416546a5b61b705a39c44534ba1835480b9
Author: Dawid Weiss <da...@carrotsearch.com>
AuthorDate: Sun Sep 6 22:42:28 2020 +0200

    LUCENE-9475: remove obsolete ant-only jar sha's from Solr.
---
 gradle/validation/jar-checks.gradle                |  11 +-
 .../android-json-0.0.20131108.vaadin1.jar.sha1     |   1 -
 solr/licenses/android-json-LICENSE-ASL.txt         | 202 ---------------------
 solr/licenses/android-json-NOTICE.txt              |   0
 solr/licenses/jsoup-1.12.1.jar.sha1                |   1 -
 solr/licenses/jsoup-LICENSE-MIT.txt                |  21 ---
 solr/licenses/slf4j-simple-1.7.24.jar.sha1         |   1 -
 solr/licenses/start.jar.sha1                       |   1 -
 8 files changed, 1 insertion(+), 237 deletions(-)

diff --git a/gradle/validation/jar-checks.gradle b/gradle/validation/jar-checks.gradle
index 61db9a1..5cdba79 100644
--- a/gradle/validation/jar-checks.gradle
+++ b/gradle/validation/jar-checks.gradle
@@ -372,16 +372,7 @@ configure(project(":lucene")) {
 configure(project(":solr")) {
   checkDanglingLicenseFiles {
     exclude += [
-        "README.committers.txt",
-
-        // solr-ref-guide compilation-only dependencies.
-        "android-json-*",
-        "ant-*",
-        "asciidoctor-ant-*",
-        "jsoup-*",
-        "junit4-ant-*",
-        "slf4j-simple-*",
-        "start.jar.sha1"
+        "README.committers.txt"
     ]
   }
 }
diff --git a/solr/licenses/android-json-0.0.20131108.vaadin1.jar.sha1 b/solr/licenses/android-json-0.0.20131108.vaadin1.jar.sha1
deleted file mode 100644
index 99a9d8e..0000000
--- a/solr/licenses/android-json-0.0.20131108.vaadin1.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-fa26d351fe62a6a17f5cda1287c1c6110dec413f
diff --git a/solr/licenses/android-json-LICENSE-ASL.txt b/solr/licenses/android-json-LICENSE-ASL.txt
deleted file mode 100644
index d645695..0000000
--- a/solr/licenses/android-json-LICENSE-ASL.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed 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.
diff --git a/solr/licenses/android-json-NOTICE.txt b/solr/licenses/android-json-NOTICE.txt
deleted file mode 100644
index e69de29..0000000
diff --git a/solr/licenses/jsoup-1.12.1.jar.sha1 b/solr/licenses/jsoup-1.12.1.jar.sha1
deleted file mode 100644
index 8228f21..0000000
--- a/solr/licenses/jsoup-1.12.1.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-55819a28fc834c2f2bcf4dcdb278524dc3cf088f
diff --git a/solr/licenses/jsoup-LICENSE-MIT.txt b/solr/licenses/jsoup-LICENSE-MIT.txt
deleted file mode 100644
index ab9f00b..0000000
--- a/solr/licenses/jsoup-LICENSE-MIT.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License
-
-© 2009-2017, Jonathan Hedley <jo...@hedley.net>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/solr/licenses/slf4j-simple-1.7.24.jar.sha1 b/solr/licenses/slf4j-simple-1.7.24.jar.sha1
deleted file mode 100644
index 043482c..0000000
--- a/solr/licenses/slf4j-simple-1.7.24.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-d9841ffd9d794ab26446df2c46a2ab2b8d2a183e
diff --git a/solr/licenses/start.jar.sha1 b/solr/licenses/start.jar.sha1
deleted file mode 100644
index ad1ad8d..0000000
--- a/solr/licenses/start.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-d5aa7d9c9cb261a9b4c460c918fd972d1a9882ed


[lucene-solr] 29/39: LUCENE-9505: add dummy outputs. (#1829)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit afb3379cc6bf27bd2aff8157fffab03576142fe5
Author: Dawid Weiss <dw...@apache.org>
AuthorDate: Fri Sep 4 11:11:57 2020 +0200

    LUCENE-9505: add dummy outputs. (#1829)
---
 gradle/defaults.gradle                           | 12 ++++++++++++
 gradle/validation/ecj-lint.gradle                |  7 ++++---
 gradle/validation/gradlew-scripts-tweaked.gradle |  6 ++++--
 gradle/validation/validate-log-calls.gradle      | 10 ++++------
 4 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/gradle/defaults.gradle b/gradle/defaults.gradle
index a011add..0ce26d1 100644
--- a/gradle/defaults.gradle
+++ b/gradle/defaults.gradle
@@ -63,5 +63,17 @@ allprojects {
     scriptResources = { buildscript ->
       return file(buildscript.sourceFile.absolutePath.replaceAll('.gradle$', ""))
     }
+
+    // LUCENE-9505: utility function that sets up dummy outputs for a task so that
+    // clean[TaskName] works and allows selective re-runs.
+    setupDummyOutputs = { Task task ->
+      File dummyOutput = file("${task.project.buildDir}/tasks/${task.name}/dummy-output.txt")
+      task.outputs.file(dummyOutput)
+      task.doLast {
+        if (!dummyOutput.exists()) {
+          dummyOutput.createNewFile()
+        }
+      }
+    }
   }
 }
diff --git a/gradle/validation/ecj-lint.gradle b/gradle/validation/ecj-lint.gradle
index 3dcb2c0..1e645d0 100644
--- a/gradle/validation/ecj-lint.gradle
+++ b/gradle/validation/ecj-lint.gradle
@@ -37,7 +37,7 @@ allprojects {
     def lintTasks = sourceSets.collect { sourceSet ->
       def srcDirs = sourceSet.java.srcDirs.findAll { dir -> dir.exists() }
 
-      tasks.create(sourceSet.getTaskName("ecjLint", null), JavaExec, {
+      tasks.create(sourceSet.getTaskName("ecjLint", null), JavaExec, {task ->
         // This dependency is on a configuration; technically it causes
         // all dependencies to be resolved before this task executes
         // (this includes scheduling tasks that compile the
@@ -46,8 +46,9 @@ allprojects {
 
         // The inputs are all source files from the sourceSet.
         inputs.files sourceSet.allSource.asFileTree
-        // The outputs are always up to date (we don't generate anything).
-        outputs.upToDateWhen { true }
+
+        // This task has no proper outputs.
+        setupDummyOutputs(task)
 
         // We create a task for all source sets but ignore those
         // that don't have any Java source directories.
diff --git a/gradle/validation/gradlew-scripts-tweaked.gradle b/gradle/validation/gradlew-scripts-tweaked.gradle
index c0bc647..fa3ba6d 100644
--- a/gradle/validation/gradlew-scripts-tweaked.gradle
+++ b/gradle/validation/gradlew-scripts-tweaked.gradle
@@ -21,14 +21,16 @@ import java.nio.charset.StandardCharsets
 // don't fork a daemon subprocess on the initial run.
 
 configure(rootProject) {
-  task gradlewScriptsTweaked() {
+  task gradlewScriptsTweaked() { task ->
     def scripts = [
         file("gradlew"),
         file("gradlew.bat")
     ]
 
     inputs.files(scripts)
-    outputs.upToDateWhen { true }
+
+    // This task has no proper outputs.
+    setupDummyOutputs(task)
 
     doFirst {
       scripts.each { file ->
diff --git a/gradle/validation/validate-log-calls.gradle b/gradle/validation/validate-log-calls.gradle
index 76fee5a..3d0566a 100644
--- a/gradle/validation/validate-log-calls.gradle
+++ b/gradle/validation/validate-log-calls.gradle
@@ -36,10 +36,13 @@ import org.apache.tools.ant.BuildException
 
 configure(subprojects.findAll { it.path.startsWith(':solr') }) {
   plugins.withType(JavaPlugin) {
-    task validateLogCalls(type: ValidateLogCallsTask) {
+    task validateLogCalls(type: ValidateLogCallsTask) { task ->
       description "Checks that log calls are either validated or conform to efficient patterns."
       group "verification"
 
+      // This task has no proper outputs.
+      setupDummyOutputs(task)
+
       sourceFiles = files(sourceSets*.java)
     }
   }
@@ -227,11 +230,6 @@ class ValidateLogCallsTask extends DefaultTask {
   @InputFiles
   FileCollection sourceFiles
 
-  ValidateLogCallsTask() {
-    // No explicit outputs (outputs always up to date).
-    outputs.upToDateWhen { true }
-  }
-
   @TaskAction
   def checkLogLines() {
     sourceFiles.each { checkFile(it) }


[lucene-solr] 22/39: master is on java 11!

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 843e61d80dc8f5f1f2a0a8a3a86067d0fdd5fc49
Author: Robert Muir <rm...@apache.org>
AuthorDate: Mon Aug 31 04:53:44 2020 -0400

    master is on java 11!
---
 .../validate-source-patterns/check-source-patterns.groovy    | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/gradle/validation/validate-source-patterns/check-source-patterns.groovy b/gradle/validation/validate-source-patterns/check-source-patterns.groovy
index 774023d..aabcd27 100644
--- a/gradle/validation/validate-source-patterns/check-source-patterns.groovy
+++ b/gradle/validation/validate-source-patterns/check-source-patterns.groovy
@@ -49,13 +49,6 @@ def invalidPatterns = [
   (~$/import java\.lang\.\w+;/$) : 'java.lang import is unnecessary'
 ]
 
-// Python and others merrily use var declarations, this is a problem _only_ in Java at least for 8x where we're forbidding var declarations
-def invalidJavaOnlyPatterns = [
-  (~$/\n\s*var\s+.*=.*<>.*/$) : 'Diamond operators should not be used with var',
-  (~$/\n\s*var\s+/$) : 'var is not allowed in until we stop development on the 8x code line'
-]
-
-
 def baseDir = properties['basedir'];
 def baseDirLen = baseDir.length() + 1;
 
@@ -209,11 +202,6 @@ ant.fileScanner{
         reportViolation(f, "Solr test cases should extend SolrTestCase rather than LuceneTestCase");
       }
     }
-    invalidJavaOnlyPatterns.each { pattern,name ->
-      if (pattern.matcher(text).find()) {
-        reportViolation(f, name);
-      }
-    }
   }
   if (f.name.endsWith('.xml') || f.name.endsWith('.xml.template')) {
     checkLicenseHeaderPrecedes(f, '<tag>', xmlTagPattern, xmlCommentPattern, text, ratDocument);


[lucene-solr] 05/39: LUCENE-9438: Eclipse IDE support with gradle build system (#1761)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit ed27e861a21ed6185f034fb1bc24a1bcd8acddf2
Author: Dawid Weiss <dw...@apache.org>
AuthorDate: Fri Aug 21 21:47:11 2020 +0200

    LUCENE-9438: Eclipse IDE support with gradle build system (#1761)
---
 build.gradle                |   5 ++-
 gradle/defaults-java.gradle |  10 ++++-
 gradle/help.gradle          |   1 +
 gradle/ide/eclipse.gradle   | 102 ++++++++++++++++++++++++++++++++++++++++++++
 help/IDEs.txt               |  20 +++++++++
 5 files changed, 135 insertions(+), 3 deletions(-)

diff --git a/build.gradle b/build.gradle
index 5e2f799..f145c73 100644
--- a/build.gradle
+++ b/build.gradle
@@ -21,8 +21,8 @@ import java.time.format.DateTimeFormatter
 plugins {
   id "base"
   id "com.palantir.consistent-versions" version "1.14.0"
-  id 'de.thetaphi.forbiddenapis' version '3.0.1' apply false
   id "org.owasp.dependencycheck" version "5.3.0"
+  id 'de.thetaphi.forbiddenapis' version '3.0.1' apply false
   id "de.undercouch.download" version "4.0.2" apply false
 }
 
@@ -63,6 +63,8 @@ ext {
   buildTime = DateTimeFormatter.ofPattern("HH:mm:ss").format(tstamp)
   buildYear = DateTimeFormatter.ofPattern("yyyy").format(tstamp)
 
+  minJavaVersion = JavaVersion.VERSION_11
+
   // Declare script dependency versions outside of palantir's
   // version unification control. These are not our main dependencies.
   scriptDepVersions = [
@@ -102,6 +104,7 @@ apply from: file('gradle/maven/defaults-maven.gradle')
 
 // IDE support, settings and specials.
 apply from: file('gradle/ide/intellij-idea.gradle')
+apply from: file('gradle/ide/eclipse.gradle')
 
 // Validation tasks
 apply from: file('gradle/validation/precommit.gradle')
diff --git a/gradle/defaults-java.gradle b/gradle/defaults-java.gradle
index 4d0fae7..e739a19 100644
--- a/gradle/defaults-java.gradle
+++ b/gradle/defaults-java.gradle
@@ -19,9 +19,15 @@
 
 allprojects {
   plugins.withType(JavaPlugin) {
-    sourceCompatibility = "11"
-    targetCompatibility = "11"
+    sourceCompatibility = rootProject.minJavaVersion
+    targetCompatibility = rootProject.minJavaVersion
 
+    // Use 'release' flag instead of 'source' and 'target'
+    tasks.withType(JavaCompile) {
+      options.compilerArgs += ["--release", rootProject.minJavaVersion.toString()]
+    }
+
+    // Configure warnings.
     tasks.withType(JavaCompile) {
       options.encoding = "UTF-8"
       options.compilerArgs += [
diff --git a/gradle/help.gradle b/gradle/help.gradle
index edee1c3..51435e1 100644
--- a/gradle/help.gradle
+++ b/gradle/help.gradle
@@ -28,6 +28,7 @@ configure(rootProject) {
       ["LocalSettings", "help/localSettings.txt", "Local settings, overrides and build performance tweaks."],
       ["Git", "help/git.txt", "Git assistance and guides."],
       ["ValidateLogCalls", "help/validateLogCalls.txt", "How to use logging calls efficiently."],
+      ["IDEs", "help/IDEs.txt", "IDE support."],
   ]
 
   helpFiles.each { section, path, sectionInfo ->
diff --git a/gradle/ide/eclipse.gradle b/gradle/ide/eclipse.gradle
new file mode 100644
index 0000000..3bebd1d
--- /dev/null
+++ b/gradle/ide/eclipse.gradle
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+import org.gradle.plugins.ide.eclipse.model.SourceFolder
+import org.gradle.plugins.ide.eclipse.model.ClasspathEntry
+
+configure(rootProject) {
+  apply plugin: "eclipse"
+
+  def relativize = { other -> rootProject.rootDir.relativePath(other).toString() }
+
+  eclipse {
+    project {
+      name = "Apache Lucene Solr ${version}"
+    }
+
+    classpath {
+      defaultOutputDir = file('build/eclipse')
+
+      file {
+        beforeMerged { classpath -> classpath.entries.removeAll { it.kind == "src" } }
+
+        whenMerged { classpath ->
+          def projects = allprojects.findAll { prj ->
+            return prj.plugins.hasPlugin(JavaPlugin) &&
+                   prj.path != ":solr:solr-ref-guide"
+          }
+
+          Set<String> sources = []
+          Set<File> jars = []
+          projects.each { prj ->
+            prj.sourceSets.each { sourceSet ->
+              sources += sourceSet.java.srcDirs.findAll { dir -> dir.exists() }.collect { dir -> relativize(dir) }
+            }
+
+            // This is hacky - we take the resolved compile classpath and just
+            // include JAR files from there. We should probably make it smarter
+            // by looking at real dependencies. But then: this Eclipse configuration
+            // doesn't really separate sources anyway so why bother.
+            jars += prj.configurations.compileClasspath.resolve()
+            jars += prj.configurations.testCompileClasspath.resolve()
+          }
+
+          classpath.entries += sources.sort().collect {name -> new SourceFolder(name, "build/eclipse/" + name) }
+          classpath.entries += jars.unique().findAll { location -> location.isFile() }.collect { location ->
+            new LibEntry(location.toString())
+          }
+        }
+      }
+    }
+
+    jdt {
+      sourceCompatibility = rootProject.minJavaVersion
+      targetCompatibility = rootProject.minJavaVersion
+      javaRuntimeName = "JavaSE-${rootProject.minJavaVersion}"
+    }
+  }
+
+  eclipseJdt {
+    doLast {
+      project.sync {
+        from rootProject.file("dev-tools/eclipse/dot.settings")
+        into rootProject.file(".settings")
+      }
+    }
+  }
+}
+
+public class LibEntry implements ClasspathEntry {
+  private String path;
+
+  LibEntry(String path) {
+    this.path = path;
+  }
+
+  @Override
+  String getKind() {
+    return "lib"
+  }
+
+  @Override
+  void appendNode(Node node) {
+    node.appendNode("classpathentry", Map.of(
+        "kind", "lib",
+        "path", path
+    ));
+  }
+}
diff --git a/help/IDEs.txt b/help/IDEs.txt
new file mode 100644
index 0000000..3ad5b85
--- /dev/null
+++ b/help/IDEs.txt
@@ -0,0 +1,20 @@
+IntelliJ IDEA
+=============
+
+Importing the project as a gradle project should just run out of the box.
+
+
+Eclipse
+=======
+
+Run the following to set up Eclipse project files:
+
+./gradlew eclipse
+
+then import the project into Eclipse with:
+
+File -> Import... -> Existing Project into Workspace
+
+Please note that Eclipse does not distinguish between sub-projects
+and package sets (main/ test) so pretty much all the sources and dependencies
+are available in one large bin.


[lucene-solr] 27/39: LUCENE-9438: Add resources to the Eclipse classpath.

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit b59438eb4b1216f6b80bc886bdf7c09b86971330
Author: Adrien Grand <jp...@gmail.com>
AuthorDate: Wed Sep 2 14:12:49 2020 +0200

    LUCENE-9438: Add resources to the Eclipse classpath.
---
 gradle/ide/eclipse.gradle | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gradle/ide/eclipse.gradle b/gradle/ide/eclipse.gradle
index e414112..12e1bdc 100644
--- a/gradle/ide/eclipse.gradle
+++ b/gradle/ide/eclipse.gradle
@@ -47,6 +47,7 @@ configure(rootProject) {
           projects.each { prj ->
             prj.sourceSets.each { sourceSet ->
               sources += sourceSet.java.srcDirs.findAll { dir -> dir.exists() }.collect { dir -> relativize(dir) }
+              sources += sourceSet.resources.srcDirs.findAll { dir -> dir.exists() }.collect { dir -> relativize(dir) }
             }
 
             // This is hacky - we take the resolved compile classpath and just


[lucene-solr] 38/39: Update versions.lock after cherry-picks

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit df4857d61f9b3313137e11733b71f0fef8bb33f9
Author: Dawid Weiss <dw...@apache.org>
AuthorDate: Mon Jul 20 12:35:29 2020 +0200

    Update versions.lock after cherry-picks
---
 build.gradle  | 18 ++++++++++++++++++
 versions.lock |  6 ++++--
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/build.gradle b/build.gradle
index 25a6185..9efac5b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -181,3 +181,21 @@ apply from: file('gradle/hacks/hashmapAssertions.gradle')
 
 apply from: file('gradle/solr/packaging.gradle')
 apply from: file('gradle/solr/solr-forbidden-apis.gradle')
+
+allprojects {
+  task ufclasspath {
+    doLast{
+      File ufPath = new File(project.getRootDir().getParentFile(), "unitflier/run/solr");
+      if (configurations.hasProperty('testRuntimeClasspath')) {
+        java.io.File file = new java.io.File(ufPath, project.projectDir.name + '.txt');
+        file.getParentFile().mkdirs();
+        file.write project.projectDir.toString() + "\n"
+        file << sourceSets.test.output.classesDirs.asPath + "\n"
+        file << project.projectDir.toString() + "/src/test-files" + ":" + project.projectDir.toString() + "/src/resources" + ":" + sourceSets.main.output.classesDirs.asPath + ":"
+        file << sourceSets.test.output.classesDirs.asPath + ":"
+        file << configurations.testRuntimeClasspath.asPath + "\n"
+      }
+    }
+  }
+}
+
diff --git a/versions.lock b/versions.lock
index b58ceda..a95d941 100644
--- a/versions.lock
+++ b/versions.lock
@@ -23,8 +23,9 @@ com.github.jnr:jnr-posix:3.0.49 (2 constraints: f0161b5b)
 com.github.jnr:jnr-unixsocket:0.20 (1 constraints: 4a09d497)
 com.github.virtuald:curvesapi:1.06 (1 constraints: db04f530)
 com.github.zafarkhaja:java-semver:0.9.0 (1 constraints: 0b050636)
-com.google.code.findbugs:jsr305:3.0.2 (1 constraints: 170aecb4)
-com.google.errorprone:error_prone_annotations:2.3.4 (1 constraints: 1b0af2b4)
+com.google.code.findbugs:annotations:3.0.1 (1 constraints: 0605fb35)
+com.google.code.findbugs:jsr305:3.0.2 (2 constraints: cd195721)
+com.google.errorprone:error_prone_annotations:2.4.0 (2 constraints: 220fdb86)
 com.google.guava:failureaccess:1.0.1 (1 constraints: 140ae1b4)
 com.google.guava:guava:29.0-jre (2 constraints: 4217cc34)
 com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava (1 constraints: bd17c918)
@@ -86,6 +87,7 @@ joda-time:joda-time:2.9.9 (1 constraints: 8a0972a1)
 junit:junit:4.12 (2 constraints: 3e1e6104)
 net.arnx:jsonic:1.2.7 (2 constraints: db10d4d1)
 net.hydromatic:eigenbase-properties:1.1.5 (1 constraints: 0905f835)
+net.jcip:jcip-annotations:1.0 (1 constraints: 560ff165)
 net.minidev:accessors-smart:1.2 (1 constraints: e60926a4)
 net.minidev:json-smart:2.3 (1 constraints: a40c49ff)
 net.sf.saxon:Saxon-HE:10.2 (1 constraints: d704f330)


[lucene-solr] 34/39: SOLR-14836: Exclude README.committers.txt from distribution

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 7a8da0a4e44daadfc8d78b2151813fddaa6f1a6f
Author: Dawid Weiss <da...@carrotsearch.com>
AuthorDate: Sun Sep 6 22:34:25 2020 +0200

    SOLR-14836: Exclude README.committers.txt from distribution
---
 solr/packaging/build.gradle | 1 +
 1 file changed, 1 insertion(+)

diff --git a/solr/packaging/build.gradle b/solr/packaging/build.gradle
index 55b78ca..5843d00 100644
--- a/solr/packaging/build.gradle
+++ b/solr/packaging/build.gradle
@@ -70,6 +70,7 @@ task toDir(type: Sync) {
   from(project(":solr").projectDir, {
     include "bin/**"
     include "licenses/**"
+    exclude "licenses/README.committers.txt"
     include "CHANGES.txt"
     include "LICENSE.txt"
     include "NOTICE.txt"


[lucene-solr] 07/39: LUCENE-9474: Make external tools configurable like in ant through those sysprops: perl.exe, python3.exe, python2.exe

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 9a8b577cc50d154df2b3eb8424ad7091c9fd1215
Author: Uwe Schindler <us...@apache.org>
AuthorDate: Sun Aug 23 20:16:22 2020 +0200

    LUCENE-9474: Make external tools configurable like in ant through those sysprops: perl.exe, python3.exe, python2.exe
---
 build.gradle                                | 7 +++++++
 gradle/documentation/changes-to-html.gradle | 2 +-
 gradle/generation/jflex.gradle              | 2 +-
 gradle/generation/kuromoji.gradle           | 2 +-
 gradle/generation/snowball.gradle           | 2 +-
 gradle/generation/util.gradle               | 4 ++--
 gradle/validation/check-broken-links.gradle | 2 +-
 gradle/validation/missing-docs-check.gradle | 2 +-
 8 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/build.gradle b/build.gradle
index 571ab30..ec5fed0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -89,6 +89,13 @@ ext {
       "jgit": "5.3.0.201903130848-r",
       "flexmark": "0.61.24",
   ]
+  
+  // read some external tool locations from system props
+  externalToolExecutables = [
+      "python3": propertyOrDefault('python3.exe', 'python3'),
+      "python2": propertyOrDefault('python2.exe', 'python2'),
+      "perl": propertyOrDefault('perl.exe', 'perl'),
+  ]
 }
 
 // Include smaller chunks configuring dedicated build areas.
diff --git a/gradle/documentation/changes-to-html.gradle b/gradle/documentation/changes-to-html.gradle
index 8d8c02e..5f56532 100644
--- a/gradle/documentation/changes-to-html.gradle
+++ b/gradle/documentation/changes-to-html.gradle
@@ -54,7 +54,7 @@ class ChangesToHtmlTask extends DefaultTask {
   def toHtml(File versionsFile) {
     def output = new ByteArrayOutputStream()
     def result = project.exec {
-      executable "perl"
+      executable project.externalToolExecutables["perl"]
       standardInput changesFile.newInputStream()
       standardOutput project.file("${targetDir.get().getAsFile()}/Changes.html").newOutputStream()
       errorOutput = output
diff --git a/gradle/generation/jflex.gradle b/gradle/generation/jflex.gradle
index 9bdbc2c..1f5feb2 100644
--- a/gradle/generation/jflex.gradle
+++ b/gradle/generation/jflex.gradle
@@ -149,7 +149,7 @@ configure(project(":lucene:analysis:common")) {
       def target = file('src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex')
       target.withOutputStream { output ->
         project.exec {
-          executable = "python"
+          executable = project.externalToolExecutables["python2"]
           workingDir = target.parentFile
           standardOutput = output
           args += [
diff --git a/gradle/generation/kuromoji.gradle b/gradle/generation/kuromoji.gradle
index 2f55c1a..c865a13 100644
--- a/gradle/generation/kuromoji.gradle
+++ b/gradle/generation/kuromoji.gradle
@@ -73,7 +73,7 @@ configure(project(":lucene:analysis:kuromoji")) {
       // Apply patch via local git.
       project.exec {
         workingDir = unpackedDir
-        executable "git"
+        executable "git" // TODO: better use jgit to apply patch, this is not portable!!!
         args += [
             "apply",
             file("src/tools/patches/Noun.proper.csv.patch").absolutePath
diff --git a/gradle/generation/snowball.gradle b/gradle/generation/snowball.gradle
index 6f7049e..b2b6882 100644
--- a/gradle/generation/snowball.gradle
+++ b/gradle/generation/snowball.gradle
@@ -100,7 +100,7 @@ configure(project(":lucene:analysis:common")) {
 
     doLast {
       project.exec {
-        executable "bash"
+        executable "bash" // TODO: does not work with windows, use project.externalToolExecutables[] instead
         args = [snowballScript, snowballStemmerDir, snowballWebsiteDir, snowballDataDir, projectDir]
       }
     }
diff --git a/gradle/generation/util.gradle b/gradle/generation/util.gradle
index 597b60a..d1a3c24 100644
--- a/gradle/generation/util.gradle
+++ b/gradle/generation/util.gradle
@@ -57,7 +57,7 @@ configure(project(":lucene:core")) {
         logger.lifecycle("Executing: ${prog} in ${targetDir}")
         project.exec {
           workingDir targetDir
-          executable "python3"
+          executable project.externalToolExecutables["python3"]
           args = ['-B', "${prog}"]
         }
       }
@@ -82,7 +82,7 @@ configure(project(":lucene:core")) {
         ['True', 'False'].each { transpose ->
           project.exec {
             workingDir targetDir
-            executable "python3"
+            executable project.externalToolExecutables["python3"]
             args = ['-B', 'createLevAutomata.py', num, transpose, "${momanDir}/finenight/python"]
           }
         }
diff --git a/gradle/validation/check-broken-links.gradle b/gradle/validation/check-broken-links.gradle
index bebfe45..2810475 100644
--- a/gradle/validation/check-broken-links.gradle
+++ b/gradle/validation/check-broken-links.gradle
@@ -52,7 +52,7 @@ class CheckBrokenLinksTask extends DefaultTask {
     def result
     outputFile.withOutputStream { output ->
       result = project.exec {
-        executable "python3"
+        executable project.externalToolExecutables["python3"]
         ignoreExitValue = true
         standardOutput = output
         errorOutput = output
diff --git a/gradle/validation/missing-docs-check.gradle b/gradle/validation/missing-docs-check.gradle
index e465997..e9cb6ae 100644
--- a/gradle/validation/missing-docs-check.gradle
+++ b/gradle/validation/missing-docs-check.gradle
@@ -89,7 +89,7 @@ class CheckMissingDocsTask extends DefaultTask {
   def checkMissingJavadocs(File dir, String level) {
     def output = new ByteArrayOutputStream()
     def result = project.exec {
-      executable "python3"
+      executable project.externalToolExecutables["python3"]
       ignoreExitValue = true
       standardOutput = output
       errorOutput = output


[lucene-solr] 17/39: LUCENE-9475: Enhance the Gradle build as necessary after removing Ant support

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 131a564331b1f3c2a272600a8f37a5f78ffab80c
Author: Erick Erickson <Er...@gmail.com>
AuthorDate: Fri Aug 28 10:13:13 2020 -0400

    LUCENE-9475: Enhance the Gradle build as necessary after removing Ant support
---
 lucene/version.properties | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/lucene/version.properties b/lucene/version.properties
deleted file mode 100644
index a00b086..0000000
--- a/lucene/version.properties
+++ /dev/null
@@ -1,10 +0,0 @@
-# This file contains some version properties as used by various build files.
-
-# RELEASE MANAGER must change this file after creating a release and
-# enter new base version (format "x.y.z", no prefix/appendix): 
-version.base=9.0.0
-
-# Other version property defaults, don't change:
-version.suffix=SNAPSHOT
-version=${version.base}-${version.suffix}
-spec.version=${version.base}


[lucene-solr] 37/39: LUCENE-9411: Fail complation on warnings, 9x gradle-only. Explicitly list warnings to check for

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 5083e02e3c88bfc388650ee682bfa6467d4202ad
Author: Erick Erickson <Er...@gmail.com>
AuthorDate: Wed Jul 8 15:51:59 2020 -0400

    LUCENE-9411: Fail complation on warnings, 9x gradle-only. Explicitly list warnings to check for
---
 gradle/defaults-java.gradle | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/gradle/defaults-java.gradle b/gradle/defaults-java.gradle
index 9495268..3f3d036 100644
--- a/gradle/defaults-java.gradle
+++ b/gradle/defaults-java.gradle
@@ -31,10 +31,24 @@ allprojects {
     tasks.withType(JavaCompile) {
       options.encoding = "UTF-8"
       options.compilerArgs += [
-        "-Xlint",
         "-Xlint:-deprecation",
         "-Xlint:-serial",
-
+        "-Xlint:cast",
+        "-Xlint:classfile",
+        "-Xlint:dep-ann",
+        "-Xlint:divzero",
+        "-Xlint:empty",
+        "-Xlint:fallthrough",
+        "-Xlint:finally",
+        "-Xlint:options",
+        "-Xlint:overrides",
+        "-Xlint:path",
+        "-Xlint:processing",
+        "-Xlint:rawtypes",
+        "-Xlint:static",
+        "-Xlint:try",
+        "-Xlint:unchecked",
+        "-Xlint:varargs",
         "-Xdoclint:all/protected",
         "-Xdoclint:-missing",
         "-Xdoclint:-accessibility",


[lucene-solr] 31/39: LUCENE-9506: Gradle: split validateSourcePatterns into per-project an… (#1830)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit e952c4fa226f6b3bdd32812a8bd47f4070873867
Author: Dawid Weiss <da...@carrotsearch.com>
AuthorDate: Tue Sep 8 10:08:51 2020 +0200

    LUCENE-9506: Gradle: split validateSourcePatterns into per-project an… (#1830)
    
    * LUCENE-9506: Gradle: split validateSourcePatterns into per-project and root-specific tasks (allow parallelism)
    
    Co-authored-by: Uwe Schindler <us...@apache.org>
---
 gradle/validation/precommit.gradle          | 5 ++---
 gradle/validation/validate-log-calls.gradle | 5 ++++-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/gradle/validation/precommit.gradle b/gradle/validation/precommit.gradle
index aad8c6f0..e4de4be 100644
--- a/gradle/validation/precommit.gradle
+++ b/gradle/validation/precommit.gradle
@@ -26,7 +26,6 @@ configure(rootProject) {
     dependsOn ":verifyLocks"
     dependsOn ":versionsPropsAreSorted"
     dependsOn ":checkWorkingCopyClean"
-    dependsOn ":validateSourcePatterns"
 
     // Solr validation tasks.
     dependsOn ":solr:validateConfigFileSanity"
@@ -40,8 +39,8 @@ configure(rootProject) {
           "javadoc",
           "rat",
           "ecjLint",
-          "checkMissingDocs",
-          "validateLogCalls"
+          "validateLogCalls",
+          "validateSourcePatterns",
       ]}
     }
   }
diff --git a/gradle/validation/validate-log-calls.gradle b/gradle/validation/validate-log-calls.gradle
index 3d0566a..caa6f5e 100644
--- a/gradle/validation/validate-log-calls.gradle
+++ b/gradle/validation/validate-log-calls.gradle
@@ -45,7 +45,10 @@ configure(subprojects.findAll { it.path.startsWith(':solr') }) {
 
       sourceFiles = files(sourceSets*.java)
     }
-  }
+ 
+    // Add log validation to per-project checks as well.
+    check.dependsOn validateLogCalls
+ }
 }
 
 class ValidateLogCallsTask extends DefaultTask {


[lucene-solr] 04/39: LUCENE-9471: clean up task and global temporary junk files (workaround). (#1767)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit ece125ac421b6bb3ca609ba5f2c696cb95db85b3
Author: Dawid Weiss <dw...@apache.org>
AuthorDate: Thu Aug 20 13:49:24 2020 +0200

    LUCENE-9471: clean up task and global temporary junk files (workaround). (#1767)
---
 build.gradle               |  4 ++--
 gradle/hacks/gradle.gradle | 51 ++++++++++++++++++++++++++++++++++++++++++++++
 gradlew                    |  9 ++++++++
 gradlew.bat                |  5 +++++
 4 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/build.gradle b/build.gradle
index f5ad04a..5e2f799 100644
--- a/build.gradle
+++ b/build.gradle
@@ -150,7 +150,7 @@ apply from: file('gradle/ant-compat/forbidden-api-rules-in-sync.gradle')
 apply from: file('gradle/documentation/documentation.gradle')
 apply from: file('gradle/documentation/changes-to-html.gradle')
 apply from: file('gradle/documentation/markdown.gradle')
-apply from: file('gradle/render-javadoc.gradle')
 apply from: file('gradle/documentation/render-javadoc.gradle')
-apply from: file('gradle/hacks/findbugs.gradle')
 
+apply from: file('gradle/hacks/findbugs.gradle')
+apply from: file('gradle/hacks/gradle.gradle')
diff --git a/gradle/hacks/gradle.gradle b/gradle/hacks/gradle.gradle
new file mode 100644
index 0000000..acb9394
--- /dev/null
+++ b/gradle/hacks/gradle.gradle
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */ 
+
+// See LUCENE-9471. We redirect temporary location for gradle
+// so that it doesn't pollute user's tmp. Wipe it during a clean though.
+
+configure(rootProject) {
+  task cleanGradleTmp(type: Delete) {
+    delete fileTree(".gradle/tmp").matching {
+      include "gradle-worker-classpath*"
+    }
+  }
+
+  clean.dependsOn cleanGradleTmp
+}
+
+// Make sure we clean up after running tests.
+allprojects {
+  plugins.withType(JavaPlugin) {
+    def temps = []
+
+    task cleanTaskTmp() {
+      doLast {
+        temps.each { temp ->
+          project.delete fileTree(temp).matching {
+            include "jar_extract*"
+          }
+        }
+      }
+    }
+
+    tasks.withType(Test) {
+      finalizedBy rootProject.cleanGradleTmp, cleanTaskTmp
+      temps += temporaryDir
+    }
+  }
+}
diff --git a/gradlew b/gradlew
index 32be99f..b275a12 100755
--- a/gradlew
+++ b/gradlew
@@ -102,12 +102,21 @@ Please set the JAVA_HOME variable in your environment to match the
 location of your Java installation."
 fi
 
+# LUCENE-9471: workaround for gradle leaving junk temp. files behind.
+GRADLE_TEMPDIR=$APP_HOME/.gradle/tmp
+mkdir -p $GRADLE_TEMPDIR
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+    GRADLE_TEMPDIR=`cygpath --path --mixed "$GRADLE_TEMPDIR"`
+fi
+DEFAULT_JVM_OPTS="$DEFAULT_JVM_OPTS \"-Djava.io.tmpdir=$GRADLE_TEMPDIR\""
+
 # LUCENE-9266: verify and download the gradle wrapper jar if we don't have one.
 if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
 fi
 GRADLE_WRAPPER_JAR=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 if ! $JAVACMD --source 11 $APP_HOME/buildSrc/src/main/java/org/apache/lucene/gradle/WrapperDownloader.java $GRADLE_WRAPPER_JAR ; then
+    echo "\nSomething went wrong. Make sure you're using Java 11 or later."
     exit $?
 fi
 
diff --git a/gradlew.bat b/gradlew.bat
index 1f58301..6f95071 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -32,6 +32,11 @@ set APP_HOME=%DIRNAME%
 @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
 
+@rem LUCENE-9471: workaround for gradle leaving junk temp. files behind.
+SET GRADLE_TEMPDIR=%DIRNAME%\.gradle\tmp
+IF NOT EXIST "%GRADLE_TEMPDIR%" MKDIR %GRADLE_TEMPDIR%
+SET DEFAULT_JVM_OPTS=%DEFAULT_JVM_OPTS% -Djava.io.tmpdir=%GRADLE_TEMPDIR%
+
 @rem Find java.exe
 if defined JAVA_HOME goto findJavaFromJavaHome
 


[lucene-solr] 21/39: LUCENE-9490: Disable both tasks in :lucene:core on Java 15+

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 4a78c206569ae56453d18de136f7a50b8d6923d6
Author: Uwe Schindler <us...@apache.org>
AuthorDate: Mon Aug 31 02:09:13 2020 +0200

    LUCENE-9490: Disable both tasks in :lucene:core on Java 15+
---
 gradle/validation/missing-docs-check.gradle | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/gradle/validation/missing-docs-check.gradle b/gradle/validation/missing-docs-check.gradle
index 57399ec..c0ee56e 100644
--- a/gradle/validation/missing-docs-check.gradle
+++ b/gradle/validation/missing-docs-check.gradle
@@ -14,6 +14,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+ 
+def javaVersionCheck = {
+  def maxSupported = JavaVersion.VERSION_14
+  def runtimeVersion = runtimeJava.javaVersion
+  if (runtimeVersion > JavaVersion.VERSION_14) {
+    logger.warn("Skipping task because runtime Java version ${runtimeVersion} is " +
+        "higher than Java ${maxSupported}.")
+    return false
+  } else {
+    return true
+  }
+}
 
 allprojects {
   plugins.withType(JavaPlugin) {
@@ -37,17 +49,7 @@ allprojects {
     task checkMissingDocsDefault(type: CheckMissingDocsTask, dependsOn: 'renderJavadoc') {
       dirs += [ project.javadoc.destinationDir ]
 
-      onlyIf {
-        def maxSupported = JavaVersion.VERSION_14
-        def runtimeVersion = runtimeJava.javaVersion
-        if (runtimeVersion > JavaVersion.VERSION_14) {
-          logger.warn("Skipping task because runtime Java version ${runtimeVersion} is " +
-              "higher than Java ${maxSupported}.")
-          return false
-        } else {
-          return true
-        }
-      }
+      onlyIf javaVersionCheck
 
       // TODO: add missing docs for all classes and bump this to level=class
       if (project.path.startsWith(":solr")) {
@@ -72,6 +74,7 @@ configure(project(':lucene:core')) {
   // Defer until java plugin has been applied, otherwise we can't resolve project.javadoc.
   plugins.withType(JavaPlugin) {
     task checkMissingDocsMethod(type: CheckMissingDocsTask, dependsOn: 'renderJavadoc') {
+      onlyIf javaVersionCheck
       level = 'method'
     }
 


[lucene-solr] 35/39: SOLR-14789: Absorb the docker-solr repo. (#1769)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 86c633dd2453e472631cf8d47c8521d178676e7c
Author: Houston Putman <ho...@apache.org>
AuthorDate: Fri Sep 11 12:29:29 2020 -0400

    SOLR-14789: Absorb the docker-solr repo. (#1769)
---
 build.gradle                                       |   1 +
 settings.gradle                                    |   2 +
 solr/docker/Docker-FAQ.md                          | 320 +++++++++++++++++++++
 solr/docker/Dockerfile                             |  75 +++++
 solr/docker/README.md                              | 275 ++++++++++++++++++
 solr/docker/build.gradle                           |  92 ++++++
 solr/docker/docs/docker-compose.yml                |  13 +
 solr/docker/docs/docker-networking.md              | 249 ++++++++++++++++
 solr/docker/docs/precreate-collection.sh           |  20 ++
 solr/docker/docs/set-heap.sh                       |  16 ++
 solr/docker/include/scripts/docker-entrypoint.sh   |  31 ++
 solr/docker/include/scripts/init-var-solr          |  61 ++++
 solr/docker/include/scripts/oom_solr.sh            |  38 +++
 solr/docker/include/scripts/precreate-core         |  40 +++
 solr/docker/include/scripts/run-initdb             |  28 ++
 solr/docker/include/scripts/solr-create            |  66 +++++
 solr/docker/include/scripts/solr-demo              |  42 +++
 solr/docker/include/scripts/solr-fg                |  56 ++++
 solr/docker/include/scripts/solr-foreground        |  15 +
 solr/docker/include/scripts/solr-precreate         |  27 ++
 solr/docker/include/scripts/start-local-solr       |  21 ++
 solr/docker/include/scripts/stop-local-solr        |  11 +
 solr/docker/include/scripts/wait-for-solr.sh       |  98 +++++++
 solr/docker/include/scripts/wait-for-zookeeper.sh  | 165 +++++++++++
 solr/docker/package/Dockerfile.local-package       |   3 +
 solr/docker/package/Dockerfile.release-package     |  74 +++++
 solr/docker/package/build.gradle                   |  36 +++
 solr/docker/tests/README.md                        |   6 +
 solr/docker/tests/cases/create_bad_core/test.sh    |  16 ++
 solr/docker/tests/cases/create_core/test.sh        |  24 ++
 solr/docker/tests/cases/create_core_exec/test.sh   |  26 ++
 .../cases/create_core_randomuser_rootgroup/test.sh |  30 ++
 solr/docker/tests/cases/demo-tini/test.sh          |  25 ++
 solr/docker/tests/cases/demo/test.sh               |  21 ++
 .../empty-varsolr-dir-ramdomuser-rootgroup/test.sh |  44 +++
 .../tests/cases/empty-varsolr-dir-solr/test.sh     |  45 +++
 .../tests/cases/empty-varsolr-dir-user/test.sh     |  42 +++
 .../empty-varsolr-vol-ramdomuser-rootgroup/test.sh |  42 +++
 .../cases/empty-varsolr-vol-solr-nocopy/test.sh    |  47 +++
 .../tests/cases/empty-varsolr-vol-solr/test.sh     |  41 +++
 .../tests/cases/empty-varsolr-vol-user/test.sh     |  48 ++++
 solr/docker/tests/cases/gosu/test.sh               |  68 +++++
 solr/docker/tests/cases/initdb/test.sh             |  50 ++++
 solr/docker/tests/cases/precreate_core/test.sh     |  24 ++
 .../precreate_core_randomuser_rootgroup/test.sh    |  29 ++
 .../docker/tests/cases/test_log4j/bogus-log4j2.xml |   1 +
 solr/docker/tests/cases/test_log4j/log4j2.xml      |  76 +++++
 solr/docker/tests/cases/test_log4j/test.sh         |  34 +++
 solr/docker/tests/cases/user_volume/test.sh        |  68 +++++
 solr/docker/tests/cases/version/test.sh            |  45 +++
 solr/docker/tests/shared.sh                        | 133 +++++++++
 51 files changed, 2860 insertions(+)

diff --git a/build.gradle b/build.gradle
index 45cb6a6..25a6185 100644
--- a/build.gradle
+++ b/build.gradle
@@ -25,6 +25,7 @@ plugins {
   id 'de.thetaphi.forbiddenapis' version '3.0.1' apply false
   id "de.undercouch.download" version "4.0.2" apply false
   id "net.ltgt.errorprone" version "1.2.1" apply false
+  id "com.palantir.docker" version "0.25.0" apply false
 }
 
 apply from: file('gradle/defaults.gradle')
diff --git a/settings.gradle b/settings.gradle
index 4ea032c..2ad25a8 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -70,3 +70,5 @@ include "solr:solr-ref-guide"
 include "solr:example"
 
 include "solr:packaging"
+include "solr:docker"
+include "solr:docker:package"
\ No newline at end of file
diff --git a/solr/docker/Docker-FAQ.md b/solr/docker/Docker-FAQ.md
new file mode 100644
index 0000000..b2a0646
--- /dev/null
+++ b/solr/docker/Docker-FAQ.md
@@ -0,0 +1,320 @@
+
+Docker Solr FAQ
+===============
+
+
+How do I persist Solr data and config?
+--------------------------------------
+
+Your data is persisted already, in your container's filesystem.
+If you `docker run`, add data to Solr, then `docker stop` and later
+`docker start`, then your data is still there. The same is true for
+changes to configuration files.
+
+Equally, if you `docker commit` your container, you can later create a new
+container from that image, and that will have your data in it.
+
+For some use-cases it is convenient to provide a modified `solr.in.sh` file to Solr.
+For example to point Solr to a ZooKeeper host:
+
+```
+docker create --name my_solr -P solr
+docker cp my_solr:/opt/solr/bin/solr.in.sh .
+sed -i -e 's/#ZK_HOST=.*/ZK_HOST=cylon.lan:2181/' solr.in.sh
+docker cp solr.in.sh my_solr:/opt/solr/bin/solr.in.sh
+docker start my_solr
+# With a browser go to http://cylon.lan:32873/solr/#/ and confirm "-DzkHost=cylon.lan:2181" in the JVM Args section.
+```
+
+But usually when people ask this question, what they are after is a way
+to store Solr data and config in a separate [Docker Volume](https://docs.docker.com/userguide/dockervolumes/).
+That is explained in the next two questions.
+
+
+How can I mount a host directory as a data volume?
+--------------------------------------------------
+
+This is useful if you want to inspect or modify the data in the Docker host
+when the container is not running, and later easily run new containers against that data.
+This is indeed possible, but there are a few gotchas.
+
+Solr stores its core data in the `server/solr` directory, in sub-directories
+for each core. The `server/solr` directory also contains configuration files
+that are part of the Solr distribution.
+Now, if we mounted volumes for each core individually, then that would
+interfere with Solr trying to create those directories. If instead we make
+the whole directory a volume, then we need to provide those configuration files
+in our volume, which we can do by copying them from a temporary container.
+For example:
+
+```
+# create a directory to store the server/solr directory
+$ mkdir /home/docker-volumes/mysolr1
+
+# make sure its host owner matches the container's solr user
+$ sudo chown 8983:8983 /home/docker-volumes/mysolr1
+
+# copy the solr directory from a temporary container to the volume
+$ docker run -it --rm -v /home/docker-volumes/mysolr1:/target apache/solr cp -r server/solr /target/
+
+# pass the solr directory to a new container running solr
+$ SOLR_CONTAINER=$(docker run -d -P -v /home/docker-volumes/mysolr1/solr:/opt/solr/server/solr apache/solr)
+
+# create a new core
+$ docker exec -it --user=solr $SOLR_CONTAINER solr create_core -c gettingstarted
+
+# check the volume on the host:
+$ ls /home/docker-volumes/mysolr1/solr/
+configsets  gettingstarted  README.txt  solr.xml  zoo.cfg
+```
+
+Note that if you add or modify files in that directory from the host, you must `chown 8983:8983` them.
+
+
+How can I use a Data Volume Container?
+--------------------------------------
+
+You can avoid the concerns about UID mismatches above, by using data volumes only from containers.
+You can create a container with a volume, then point future containers at that same volume.
+This can be handy if you want to modify the solr image, for example if you want to add a program.
+By separating the data and the code, you can change the code and re-use the data.
+
+But there are pitfalls:
+
+- if you remove the container that owns the volume, then you lose your data.
+  Docker does not even warn you that a running container is dependent on it.
+- if you point multiple solr containers at the same volume, you will have multiple instances
+  write to the same files, which will undoubtedly lead to corruption
+- if you do want to remove that volume, you must do `docker rm -v containername`;
+  if you forget the `-v` there will be a dangling volume which you can not easily clean up.
+
+Here is an example:
+
+```
+# create a container with a volume on the path that solr uses to store data.
+docker create -v /opt/solr/server/solr --name mysolr1data solr /bin/true
+
+# pass the volume to a new container running solr
+SOLR_CONTAINER=$(docker run -d -P --volumes-from=mysolr1data apache/solr)
+
+# create a new core
+$ docker exec -it --user=solr $SOLR_CONTAINER solr create_core -c gettingstarted
+
+# make a change to the config, using the config API
+docker exec -it --user=solr $SOLR_CONTAINER curl http://localhost:8983/solr/gettingstarted/config -H 'Content-type:application/json' -d'{
+    "set-property" : {"query.filterCache.autowarmCount":1000},
+    "unset-property" :"query.filterCache.size"}'
+
+# verify the change took effect
+docker exec -it --user=solr $SOLR_CONTAINER curl http://localhost:8983/solr/gettingstarted/config/overlay?omitHeader=true
+
+# stop the solr container
+docker exec -it --user=solr $SOLR_CONTAINER bash -c 'cd server; java -DSTOP.PORT=7983 -DSTOP.KEY=solrrocks -jar start.jar --stop'
+
+# create a new container
+SOLR_CONTAINER=$(docker run -d -P --volumes-from=mysolr1data apache/solr)
+
+# check our core is still there:
+docker exec -it --user=solr $SOLR_CONTAINER ls server/solr/gettingstarted
+
+# check the config modification is still there:
+docker exec -it --user=solr $SOLR_CONTAINER curl http://localhost:8983/solr/gettingstarted/config/overlay?omitHeader=true
+```
+
+
+Can I use volumes with SOLR_HOME?
+---------------------------------
+
+Solr supports a SOLR_HOME environment variable to point to a non-standard location of the Solr home directory.
+You can use this in Solr docker, in combination with volumes:
+
+```
+docker run -it -v $PWD/mysolrhome:/mysolrhome -e SOLR_HOME=/mysolrhome apache/solr
+```
+
+This does need a pre-configured directory at that location.
+
+To make this easier, Solr docker supports a INIT_SOLR_HOME setting, which copies the contents
+from the default directory in the image to the SOLR_HOME (if it is empty).
+
+```
+mkdir mysolrhome
+sudo chown 8983:8983 mysolrhome
+docker run -it -v $PWD/mysolrhome:/mysolrhome -e SOLR_HOME=/mysolrhome -e INIT_SOLR_HOME=yes apache/solr
+```
+
+Note: If SOLR_HOME is set, the "solr-precreate" command will put the created core in the SOLR_HOME directory
+rather than the "mycores" directory.
+
+
+Can I run ZooKeeper and Solr clusters under Docker?
+---------------------------------------------------
+
+At the network level the ZooKeeper nodes need to be able to talk to eachother,
+and the Solr nodes need to be able to talk to the ZooKeeper nodes and to each other.
+At the application level, different nodes need to be able to identify and locate each other.
+In ZooKeeper that is done with a configuration file that lists hostnames or IP addresses for each node.
+In Solr that is done with a parameter that specifies a host or IP address, which is then stored in ZooKeeper.
+
+In typical clusters, those hostnames/IP addresses are pre-defined and remain static through the lifetime of the cluster.
+In Docker, inter-container communication and multi-host networking can be facilitated by [Docker Networks](https://docs.docker.com/engine/userguide/networking/).
+But, crucially, Docker does not normally guarantee that IP addresses of containers remain static during the lifetime of a container.
+In non-networked Docker, the IP address seems to change everytime you stop/start.
+In a networked Docker, containers can lose their IP address in certain sequences of starting/stopping, unless you take steps to prevent that.
+
+IP changes causes problems:
+
+- If you use hardcoded IP addresses in configuration, and the addresses of your containers change after a stops/start, then your cluster will stop working and may corrupt itself.
+- If you use hostnames in configuration, and the addresses of your containers change, then you might run into problems with cached hostname lookups.
+- And if you use hostnames there is another problem: the names are not defined until the respective container is running,
+So when for example the first ZooKeeper node starts up, it will attempt a hostname lookup for the other nodes, and that will fail.
+This is especially a problem for ZooKeeper 3.4.6; future versions are better at recovering.
+
+Docker 1.10 has a new `--ip` configuration option that allows you to specify an IP address for a container.
+It also has a `--ip-range` option that allows you to specify the range that other containers get addresses from.
+Used together, you can implement static addresses. See [this example](docs/docker-networking.md).
+
+
+Can I run ZooKeeper and Solr with Docker Links?
+-----------------------------------------------
+
+Docker's [Legacy container links](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/) provide a way to
+pass connection configuration between containers. It only works on a single machine, on the default bridge.
+It provides no facilities for static IPs.
+Note: this feature is expected to be deprecated and removed in a future release.
+So really, see the "Can I run ZooKeeper and Solr clusters under Docker?" option above instead.
+
+But for some use-cases, such as quick demos or one-shot automated testing, it can be convenient.
+
+Run ZooKeeper, and define a name so we can link to it:
+
+```console
+$ docker run --name zookeeper -d -p 2181:2181 -p 2888:2888 -p 3888:3888 jplock/zookeeper
+```
+
+Run two Solr nodes, linked to the zookeeper container:
+
+```console
+$ docker run --name solr1 --link zookeeper:ZK -d -p 8983:8983 \
+      apache/solr \
+      bash -c 'solr start -f -z $ZK_PORT_2181_TCP_ADDR:$ZK_PORT_2181_TCP_PORT'
+
+$ docker run --name solr2 --link zookeeper:ZK -d -p 8984:8983 \
+      apache/solr \
+      bash -c 'solr start -f -z $ZK_PORT_2181_TCP_ADDR:$ZK_PORT_2181_TCP_PORT'
+```
+
+Create a collection:
+
+```console
+$ docker exec -i -t solr1 solr create_collection \
+        -c gettingstarted -shards 2 -p 8983
+```
+
+Then go to `http://localhost:8983/solr/#/~cloud` (adjust the hostname for your docker host) to see the two shards and Solr nodes.
+
+
+How can I run ZooKeeper and Solr with Docker Compose?
+-----------------------------------------------------
+
+See the [docker compose example](docs/docker-compose.yml).
+
+
+I'm confused about the different invocations of solr -- help?
+-------------------------------------------------------------
+
+The different invocations of the Solr docker image can look confusing, because the name of the
+image is "apache/solr" and the Solr command is also "solr", and the image interprets various arguments in
+special ways. I'll illustrate the various invocations:
+
+
+To run an arbitrary command in the image:
+
+```
+docker run -it apache/solr date
+```
+
+here "apache/solr" is the name of the image, and "date" is the command.
+This does not invoke any solr functionality.
+
+
+To run the Solr server:
+
+```
+docker run -it apache/solr
+```
+
+Here "apache/solr" is the name of the image, and there is no specific command,
+so the image defaults to run the "solr" command with "-f" to run it in the foreground.
+
+
+To run the Solr server with extra arguments:
+
+```
+docker run -it apache/solr -h myhostname
+```
+
+This is the same as the previous one, but an additional argument is passed.
+The image will run the "solr" command with "-f -h myhostname"
+
+To run solr as an arbitrary command:
+
+```
+docker run -it apache/solr solr zk --help
+```
+
+here the first "apache/solr" is the image name, and the second "solr"
+is the "solr" command. The image runs the command exactly as specified;
+no "-f" is implicitly added. The container will print help text, and exit.
+
+If you find this visually confusing, it might be helpful to use more specific image tags,
+and specific command paths. For example:
+
+```
+docker run -it apache/solr:6 bin/solr -f -h myhostname
+```
+
+Finally, the Solr docker image offers several commands that do some work before
+then invoking the Solr server, like "solr-precreate" and "solr-demo".
+See the README.md for usage.
+These are implemented by the `docker-entrypoint.sh` script, and must be passed
+as the first argument to the image. For example:
+
+```
+docker run -it apache/solr:6 solr-demo
+```
+
+It's important to understand an implementation detail here. The Dockerfile uses
+`solr-foreground` as the `CMD`, and the `docker-entrypoint.sh` implements
+that by by running "solr -f". So these two are equivalent:
+
+```
+docker run -it apache/solr:6
+docker run -it apache/solr:6 solr-foreground
+```
+
+whereas:
+
+```
+docker run -it apache/solr:6 solr -f
+```
+
+is slightly different: the "solr" there is a generic command, not treated in any
+special way by `docker-entrypoint.sh`. In particular, this means that the
+`docker-entrypoint-initdb.d` mechanism is not applied.
+So, if you want to use `docker-entrypoint-initdb.d`, then you must use one
+of the other two invocations.
+You also need to keep that in mind when you want to invoke solr from the bash
+command. For example, this does NOT run `docker-entrypoint-initdb.d` scripts:
+
+```
+docker run -it -v $PWD/set-heap.sh:/docker-entrypoint-initdb.d/set-heap.sh \
+    apache/solr:6 bash -c "echo hello; solr -f"
+```
+
+but this does:
+
+```
+docker run -it $PWD/set-heap.sh:/docker-entrypoint-initdb.d/set-heap.sh \
+    apache/solr:6 bash -c "echo hello; /opt/docker-solr/scripts/docker-entrypoint.sh solr-foreground"
+```
diff --git a/solr/docker/Dockerfile b/solr/docker/Dockerfile
new file mode 100644
index 0000000..26bbfdd
--- /dev/null
+++ b/solr/docker/Dockerfile
@@ -0,0 +1,75 @@
+ARG SOLR_PACKAGE_IMAGE
+ARG BASE_IMAGE=openjdk:11-jre-slim
+
+FROM $SOLR_PACKAGE_IMAGE as solr_package
+
+FROM $BASE_IMAGE as runtime
+
+LABEL maintainer="The Apache Lucene/Solr Project"
+LABEL repository="https://github.com/apache/lucene-solr"
+
+# Override the default github URL to provide a mirror for github releases.
+ARG GITHUB_URL=github.com
+
+RUN set -ex; \
+    apt-get update; \
+    apt-get -y install acl dirmngr gpg lsof procps wget netcat gosu tini; \
+    rm -rf /var/lib/apt/lists/*; \
+    cd /usr/local/bin; wget -nv https://${GITHUB_URL}/apangin/jattach/releases/download/v1.5/jattach; chmod 755 jattach; \
+    echo >jattach.sha512 "d8eedbb3e192a8596c08efedff99b9acf1075331e1747107c07cdb1718db2abe259ef168109e46bd4cf80d47d43028ff469f95e6ddcbdda4d7ffa73a20e852f9  jattach"; \
+    sha512sum -c jattach.sha512; rm jattach.sha512
+
+ENV SOLR_USER="solr" \
+    SOLR_UID="8983" \
+    SOLR_GROUP="solr" \
+    SOLR_GID="8983" \
+    PATH="/opt/solr/bin:/opt/docker-solr/scripts:$PATH" \
+    SOLR_INCLUDE=/etc/default/solr.in.sh \
+    SOLR_HOME=/var/solr/data \
+    SOLR_PID_DIR=/var/solr \
+    SOLR_LOGS_DIR=/var/solr/logs \
+    LOG4J_PROPS=/var/solr/log4j2.xml \
+    SOLR_JETTY_HOST="0.0.0.0"
+
+RUN set -ex; \
+  groupadd -r --gid "$SOLR_GID" "$SOLR_GROUP"; \
+  useradd -r --uid "$SOLR_UID" --gid "$SOLR_GID" "$SOLR_USER"
+
+COPY --chown=0:0 scripts /opt/docker-solr/scripts
+
+ARG SOLR_VERSION
+
+COPY --from=solr_package "/opt/solr-$SOLR_VERSION.tgz" "/opt/solr-$SOLR_VERSION.tgz"
+
+RUN set -ex; \
+  tar -C /opt --extract --file "/opt/solr-$SOLR_VERSION.tgz" && \
+  rm "/opt/solr-$SOLR_VERSION.tgz"; \
+  (cd /opt; ln -s "solr-$SOLR_VERSION" solr); \
+  rm -Rf /opt/solr/docs/ /opt/solr/dist/{solr-solrj-$SOLR_VERSION.jar,solrj-lib,solr-test-framework-$SOLR_VERSION.jar,test-framework}; \
+  mkdir -p /opt/solr/server/solr/lib /docker-entrypoint-initdb.d /opt/docker-solr; \
+  chown -R 0:0 "/opt/solr-$SOLR_VERSION"; \
+  find "/opt/solr-$SOLR_VERSION" -type d -print0 | xargs -0 chmod 0755; \
+  find "/opt/solr-$SOLR_VERSION" -type f -print0 | xargs -0 chmod 0644; \
+  chmod -R 0755 "/opt/solr-$SOLR_VERSION/bin" "/opt/solr-$SOLR_VERSION/contrib/prometheus-exporter/bin/solr-exporter" /opt/solr-$SOLR_VERSION/server/scripts/cloud-scripts; \
+  cp /opt/solr/bin/solr.in.sh /etc/default/solr.in.sh; \
+  mv /opt/solr/bin/solr.in.sh /opt/solr/bin/solr.in.sh.orig; \
+  mv /opt/solr/bin/solr.in.cmd /opt/solr/bin/solr.in.cmd.orig; \
+  chown root:0 /etc/default/solr.in.sh; \
+  chmod 0664 /etc/default/solr.in.sh; \
+  mkdir -p /var/solr/data /var/solr/logs; \
+  (cd /opt/solr/server/solr; cp solr.xml zoo.cfg /var/solr/data/); \
+  cp /opt/solr/server/resources/log4j2.xml /var/solr/log4j2.xml; \
+  find /var/solr -type d -print0 | xargs -0 chmod 0770; \
+  find /var/solr -type f -print0 | xargs -0 chmod 0660; \
+  sed -i -e "s/\"\$(whoami)\" == \"root\"/\$(id -u) == 0/" /opt/solr/bin/solr; \
+  sed -i -e 's/lsof -PniTCP:/lsof -t -PniTCP:/' /opt/solr/bin/solr; \
+  chown -R "0:0" /opt/solr-$SOLR_VERSION /docker-entrypoint-initdb.d /opt/docker-solr; \
+  chown -R "$SOLR_USER:0" /var/solr;
+
+VOLUME /var/solr
+EXPOSE 8983
+WORKDIR /opt/solr
+USER $SOLR_USER
+
+ENTRYPOINT ["docker-entrypoint.sh"]
+CMD ["solr-foreground"]
diff --git a/solr/docker/README.md b/solr/docker/README.md
new file mode 100644
index 0000000..3356419
--- /dev/null
+++ b/solr/docker/README.md
@@ -0,0 +1,275 @@
+# Supported tags and respective `Dockerfile` links
+
+See [Docker Hub](https://hub.docker.com/apache/solr?tab=tags) for a list of image tags available to pull.
+
+# Getting started with the Docker image
+
+Instructions below apply to `apache/solr:8.0.0` and above.
+
+## Running Solr with host-mounted directories
+
+Typically users first want to run a single standalone Solr server in a container, with a single core for data, while storing data in a local directory.
+This is a convenient mechanism for developers, and could be used for single-server production hosts too.
+
+```console
+$ mkdir solrdata
+$ docker run -d -v "$PWD/solrdata:/var/solr" -p 8983:8983 --name my_solr apache/solr solr-precreate gettingstarted
+```
+
+Then with a web browser go to `http://localhost:8983/` to see the Admin Console (adjust the hostname for your docker host).
+In the web UI if you click on "Core Admin" you should now see the "gettingstarted" core.
+
+Next load some of the example data that is included in the container:
+
+```console
+$ docker exec -it my_solr post -c gettingstarted example/exampledocs/manufacturers.xml
+```
+
+In the UI, find the "Core selector" popup menu and select the "gettingstarted" core, then select the "Query" menu item. This gives you a default search for `*:*` which returns all docs. Hit the "Execute Query" button, and you should see a few docs with data. Congratulations!
+
+
+# Single server with Docker-compose
+
+You can use Docker Compose to run a single standalone server.
+And you could use Docker Volumes instead of host-mounted directories.
+For example, with a `docker-compose.yml` containing the following:
+
+```yaml
+version: '3'
+services:
+  solr:
+    image: apache/solr
+    ports:
+     - "8983:8983"
+    volumes:
+      - data:/var/solr
+    command:
+      - solr-precreate
+      - gettingstarted
+volumes:
+  data:
+```
+
+you can simply run:
+
+```console
+docker-compose up -d
+```
+
+## Single-command demo
+
+For quick demos of Solr docker, there is a single command that starts Solr, creates a collection called "demo", and loads sample data into it:
+
+```console
+$ docker run --name solr_demo -d -p 8983:8983 apache/solr solr-demo
+```
+## Distributed Solr
+
+See [this example](docs/docker-compose.yml)
+for an example Docker Compose file that starts up Solr in a simple cluster configuration.
+
+# How the image works
+
+The container contains an installation of Solr, as installed by the [service installation script](https://lucene.apache.org/solr/guide/7_7/taking-solr-to-production.html#service-installation-script).
+This stores the Solr distribution in `/opt/solr`, and configures Solr to use `/var/solr` to store data and logs, using the `/etc/default/solr` file for configuration.
+If you want to persist the data, mount a volume or directory on `/var/solr`.
+Solr expects some files and directories in `/var/solr`; if you use your own directory or volume you can either pre-populate them, or let Solr docker copy them for you. See [init-var-solr](scripts/init-var-solr).
+If you want to use custom configuration, mount it in the appropriate place. See below for examples.
+
+The Solr docker distribution adds [scripts](include/scripts) in `/opt/docker-solr/scripts` to make it easier to use under Docker, for example to create cores on container startup.
+
+## Creating cores
+
+When Solr runs in standalone mode, you create "cores" to store data. On a non-Docker Solr, you would run the server in the background, then use the [Solr control script](https://lucene.apache.org/solr/guide/7_7/solr-control-script-reference.html) to create cores and load data. With Solr docker you have various options.
+
+The first is exactly the same: start Solr running in a container, then execute the control script manually in the same container:
+
+```console
+$ docker run -d -p 8983:8983 --name my_solr apache/solr
+$ docker exec -it my_solr solr create_core -c gettingstarted
+```
+
+This is not very convenient for users, and makes it harder to turn it into configuration for Docker Compose and orchestration tools like Kubernetes.
+So, typically you will use the `solr-precreate` command which prepares the specified core and then runs Solr:
+
+```console
+$ docker run -d -p 8983:8983 --name my_solr apache/solr solr-precreate gettingstarted
+```
+
+The `solr-precreate` command takes an optional extra argument to specify a configset directory below `/opt/solr/server/solr/configsets/`.
+This allows you to specify your own config. See [this example](https://github.com/docker-solr/docker-solr-examples/tree/master/custom-configset).
+
+The third option is to use the `solr-create` command. This runs a Solr in the background in the container, then uses the Solr control script to create the core, then stops the Solr server and restarts it in the foreground. This method is less popular because the double Solr run can be confusing.
+
+```console
+$ docker run -d -p 8983:8983 --name my_solr apache/solr solr-create -c gettingstarted
+```
+
+Finally, you can run your own command-line and specify what to do, and even invoke mounted scripts. For example:
+
+```console
+$ docker run -p 8983:8983 -v $PWD/mysetup.sh:/mysetup.sh --name my_solr apache/solr bash -c "precreate-core gettingstarted && source /mysetup.sh && solr-foreground"
+```
+
+## Creating collections
+
+In a "SolrCloud" cluster you create "collections" to store data; and again you have several options for creating a core.
+
+These examples assume you're running [this example cluster](docs/docker-compose.yml)
+
+The first way to create a collection is to go to the [Solr Admin UI](http://localhost:8983/), select "Collections" from the left-hand side navigation menu, then press the "Add Collection" button, give it a name, select the `_default` config set, then press the "Add Collection" button.
+
+The second way is through the Solr control script on one of the containers:
+
+```console
+$ docker exec solr1 solr create -c gettingstarted2
+```
+
+The third way is to use a separate container:
+
+```console
+$ docker run -e SOLR_HOST=solr1 --network docs_solr apache/solr solr create_collection -c gettingstarted3 -p 8983
+```
+
+The fourth way is to use the remote API, from the host or from one of the containers, or some new container on the same network (adjust the hostname accordingly):
+
+```console
+curl 'http://localhost:8983/solr/admin/collections?action=CREATE&name=gettingstarted3&numShards=1&collection.configName=_default'
+```
+
+If you want to use a custom config for your collection, you first need to upload it, and then refer to it by name when you create the collection.
+See the Ref guide on how to use the [ZooKeeper upload](https://lucene.apache.org/solr/guide/7_7/solr-control-script-reference.html) or the [configset API](https://lucene.apache.org/solr/guide/7_0/configsets-api.html).
+
+
+## Loading your own data
+
+There are several ways to load data; let's look at the most common ones.
+
+The most common first deployment is to run Solr standalone (not in a cluster), on a workstation or server, where you have local data you wish to load.
+One way of doing that is using a separate container, with a mounted volume containing the data, using the host network so you can connect to the mapped port:
+
+```console
+# start Solr. Listens on localhost:8983
+$ docker run --name my_solr -p 8983:8983 apache/solr solr-precreate books
+
+# get data
+$ mkdir mydata
+$ wget -O mydata/books.csv https://raw.githubusercontent.com/apache/lucene-solr/master/solr/example/exampledocs/books.csv
+$ docker run --rm -v "$PWD/mydata:/mydata" --network=host apache/solr post -c books /mydata/books.csv
+```
+
+If you use the [this example cluster](docs/docker-compose.yml) the same works, or you can just start your loading container in the same network:
+
+```console
+$ docker run -e SOLR_HOST=solr1 --network=mycluster_solr apache/solr solr create_collection -c books -p 8983
+$ docker run --rm -v "$PWD/mydata:/mydata" --network=mycluster_solr apache/solr post  -c books /mydata/books.csv -host solr1
+```
+
+Alternatively, you can make the data available on a volume at Solr start time, and then load it from `docker exec` or a custom start script.
+
+
+## solr.in.sh configuration
+
+In Solr it is common to configure settings in [solr.in.sh](https://github.com/apache/lucene-solr/blob/master/solr/bin/solr.in.sh),
+as documented in the [Solr Reference Guide](https://cwiki.apache.org/confluence/display/solr/Taking+Solr+to+Production#TakingSolrtoProduction-Environmentoverridesincludefile).
+
+The `solr.in.sh` file can be found in `/etc/default`:
+
+```console
+$ docker run apache/solr cat /etc/default/solr.in.sh
+```
+
+It has various commented-out values, which you can override when running the container, like:
+
+```
+$ docker run -d -p 8983:8983 -e SOLR_HEAP=800m apache/solr
+```
+
+You can also mount your own config file. Do no modify the values that are set at the end of the file.
+
+## Extending the image
+
+The Solr docker image has an extension mechanism. At run time, before starting Solr, the container will execute scripts
+in the `/docker-entrypoint-initdb.d/` directory. You can add your own scripts there either by using mounted volumes
+or by using a custom Dockerfile. These scripts can for example copy a core directory with pre-loaded data for continuous
+integration testing, or modify the Solr configuration.
+
+Here is a simple example. With a `custom.sh` script like:
+
+```console
+#!/bin/bash
+set -e
+echo "this is running inside the container before Solr starts"
+```
+
+you can run:
+
+```console
+$ docker run --name solr_custom1 -d -v $PWD/custom.sh:/docker-entrypoint-initdb.d/custom.sh apache/solr
+$ sleep 5
+$ docker logs solr_custom1 | head
+/opt/docker-solr/scripts/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/set-heap.sh
+this is running inside the container before Solr starts
+
+Starting Solr on port 8983 from /opt/solr/server
+```
+
+With this extension mechanism it can be useful to see the shell commands that are being executed by the `docker-entrypoint.sh`
+script in the docker log. To do that, set an environment variable using Docker's `-e VERBOSE=yes`.
+
+Instead of using this mechanism, you can of course create your own script that does setup and then call `solr-foreground`, mount that script into the container, and execute it as a command when running the container.
+
+Other ways of extending the image are to create custom Docker images that inherit from this one.
+
+## Debugging with jattach
+
+The `jcmd`, `jmap` `jstack` tools can be useful for debugging Solr inside the container. These tools are not included with the JRE, but this image includes the [jattach](https://github.com/apangin/jattach) utility which lets you do much of the same.
+
+    Usage: jattach <pid> <cmd> [args ...]
+    
+      Commands: 
+        load : load agent library
+        properties : print system properties
+        agentProperties : print agent properties
+        datadump : show heap and thread summary
+        threaddump : dump all stack traces (like jstack)
+        dumpheap : dump heap (like jmap)
+        inspectheap : heap histogram (like jmap -histo)
+        setflag : modify manageable VM flag
+        printflag : print VM flag
+        jcmd : execute jcmd command
+    
+Example comands to do a thread dump and get heap info for PID 10:
+
+    jattach 10 threaddump
+    jattach 10 jcmd GC.heap_info
+
+# Updating from Docker-solr5-7 to 8
+
+For Solr 8, the docker-solr distribution switched from just extracting the Solr tar, to using the [service installation script](https://lucene.apache.org/solr/guide/7_7/taking-solr-to-production.html#service-installation-script). This was done for various reasons: to bring it in line with the recommendations by the Solr Ref Guide, to make it easier to mount volumes, and because we were [asked to](https://github.com/docker-solr/docker-solr/issues/173).
+
+This is a backwards incompatible change, and means that if you're upgrading from an older version, you will most likely need to make some changes. If you don't want to upgrade at this time, specify `apache/solr:7` as your container image. If you use `solr:8` you will use the new style. If you use just `solr` then you risk being tripped up by backwards incompatible changes; always specify at least a major version.
+
+Changes:
+
+- The Solr data is now stored in `/var/solr/data` rather than `/opt/solr/server/solr`. The `/opt/solr/server/solr/mycores` no longer exists
+- The custom `SOLR_HOME` can no longer be used, because various scripts depend on the new locations. Consequently, `INIT_SOLR_HOME` is also no longer supported.
+
+# Running under tini
+
+The Solr docker image runs Solr under [tini](https://github.com/krallin/tini), to make signal handling work better; in particular, this allows you to `kill -9` the JVM. If you run `docker run --init`, or use `init: true` in `docker-compose.yml`, or have added `--init` to `dockerd`, docker will start its `tini` and docker-solr will notice it is not PID 1, and just `exec` Solr. If you do not run with `--init`, then the docker entrypoint script detects that it is running as PID 1, and will  [...]
+
+# Out of memory handling
+
+You can use the `OOM` environment variable to control the behaviour of the Solr JVM when an out-of-memory error occurs.
+If you specify `OOM=exit`, Solr docker will add `-XX:+ExitOnOutOfMemoryError` to the JVM arguments, so that the JVM will exit.
+If you specify `OOM=crash`, Solr docker will add `-XX:+CrashOnOutOfMemoryError` to the JVM arguments, so the JVM will crash and produces text and binary crash files (if core files are enabled).
+If you specify `OOM=script`, Solr docker will add `-XX:OnOutOfMemoryError=/opt/docker-solr/scripts/oom_solr.sh`, so the JVM will run that script (and if you want to you can mount your own in its place).
+
+# About this repository
+
+This repository is available on , and the official build is on the [Docker Hub](https://hub.docker.com/apache/solr/).
+
+# History
+
+This project was started in 2015 by [Martijn Koster](https://github.com/makuk66) in the [docker-solr](https://github.com/docker-solr/docker-solr) repository. In 2019 maintainership and copyright was transferred to the Apache Lucene/Solr project, and in 2020 the project was migrated to live within the Solr project. Many thanks to Martijn for all your contributions over the years!
\ No newline at end of file
diff --git a/solr/docker/build.gradle b/solr/docker/build.gradle
new file mode 100644
index 0000000..a634812
--- /dev/null
+++ b/solr/docker/build.gradle
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+apply plugin: 'base'
+apply plugin: 'com.palantir.docker'
+
+subprojects {
+  apply plugin: 'base'
+  apply plugin: 'com.palantir.docker'
+}
+
+description = 'Solr Docker image'
+
+def dockerPackage = project(':solr:docker:package')
+
+dependencies {
+  docker dockerPackage
+}
+
+docker {
+  name = "apache/solr:${version}"
+  files file('include')
+  buildArgs(['BASE_IMAGE' : 'openjdk:11-jre-slim', 'SOLR_PACKAGE_IMAGE' : 'apache/solr-build:local-package', 'SOLR_VERSION': "${version}"])
+}
+
+// In order to create the solr docker image, the solr package image must be created first.
+tasks.docker.dependsOn(dockerPackage.tasks.docker)
+
+abstract class DockerTestSuite extends DefaultTask {
+  private List<String> tests = new ArrayList<>();
+  private List<String> ignore = new ArrayList<>();
+
+  @OutputDirectory
+  abstract DirectoryProperty getOutputDir()
+
+  @Option(option = "tests", description = "Only run these specified tests, comma separated.")
+  public void setTests(List<String> tests) {
+    this.tests = tests;
+  }
+
+  @Input
+  public List<String> getTests() {
+    return tests;
+  }
+
+  @Option(option = "ignore", description = "Ignore these tests, comma separated.")
+  public void setIgnore(List<String> ignore) {
+    this.ignore = ignore;
+  }
+
+  @Input
+  public List<String> getIgnore() {
+    return ignore;
+  }
+
+  @TaskAction
+  void execute() {
+    def sourceDir = project.file("tests/cases")
+    sourceDir.eachFile  { file ->
+      def testName = file.getName()
+      def testCaseBuildDir = outputDir.dir(testName).get().toString()
+
+      // If specific tests are specified, only run those. Otherwise run all that are not ignored.
+      def runTest = !this.tests.isEmpty() ? tests.contains(testName) : !ignore.contains(testName)
+      if (runTest) {
+        project.exec {
+          environment "TEST_DIR", "$file"
+          environment "BUILD_DIR", "$testCaseBuildDir"
+          commandLine "bash", "$file/test.sh", "apache/solr:${project.version}"
+        }
+      }
+    }
+  }
+}
+
+task test(type: DockerTestSuite) {
+  outputDir = project.file("$buildDir/tmp/tests")
+}
\ No newline at end of file
diff --git a/solr/docker/docs/docker-compose.yml b/solr/docker/docs/docker-compose.yml
new file mode 100644
index 0000000..e2b5934
--- /dev/null
+++ b/solr/docker/docs/docker-compose.yml
@@ -0,0 +1,13 @@
+version: '3'
+services:
+  solr:
+    image: apache/solr
+    ports:
+     - "8983:8983"
+    volumes:
+      - data:/var/solr
+    command:
+      - solr-precreate
+      - gettingstarted
+volumes:
+  data:
diff --git a/solr/docker/docs/docker-networking.md b/solr/docker/docs/docker-networking.md
new file mode 100644
index 0000000..ff5e4d4
--- /dev/null
+++ b/solr/docker/docs/docker-networking.md
@@ -0,0 +1,249 @@
+Example of Zookeeper and Solr cluster with Docker networking
+------------------------------------------------------------
+
+_Note: this article dates from Jan 2016. While this approach would still work, in Jan 2019 this would typically done with Docker cluster and orchestration tools like Kubernetes. See for example [this blog post](https://lucidworks.com/2019/02/07/running-solr-on-kubernetes-part-1/)._
+
+In this example I'll create a cluster with 3 ZooKeeper nodes and 3 Solr nodes, distributed over 3 machines (trinity10, trinity20, trinity30).
+I'll use an overlay network, specify fixed IP addresses when creating containers, and I'll pass in explicit `/etc/hosts` entries to make sure they are available even when nodes are down.
+I won't show the configuration of the key-value store to configuration to enable networking, see [the docs](https://docs.docker.com/engine/userguide/networking/get-started-overlay/) for that.
+I'll not use Docker Swarm in this example, but specifically place and configure containers where I want them by ssh'ing into the appropriate Docker host.
+
+To make this example easier to understand I'll just use shell commands.
+For actual use you may want to use a fancier deployment tool like [Fabric](http://www.fabfile.org).
+
+Note: this example requires Docker 1.10.
+
+I'll run these commands from the first machine, trinity10.
+
+Create a network named "netzksolr" for this cluster. The `--ip-range` specifies the range of
+addresses to use for containers, whereas the `--subnet` specifies all possible addresses in this
+network. So effectively, addresses in the subnet but outside the range are reserved for containers
+that specifically use the `--ip` option.
+
+```
+docker network create --driver=overlay --subnet 192.168.22.0/24 --ip-range=192.168.22.128/25 netzksolr
+```
+
+As a simple test, check the automatic assignment and specific assignment work:
+
+```
+$ docker run -i --rm --net=netzksolr busybox ip -4 addr show eth0 | grep inet
+    inet 192.168.23.129/24 scope global eth0
+$ docker run -i --rm --net=netzksolr --ip=192.168.22.5 busybox ip -4 addr show eth0 | grep inet
+    inet 192.168.22.5/24 scope global eth0
+```
+
+So next create containers for ZooKeeper nodes.
+First define some environment variables for convenience:
+
+```
+# the machine to run the container on
+ZK1_HOST=trinity10.lan
+ZK2_HOST=trinity20.lan
+ZK3_HOST=trinity30.lan
+
+# the IP address for the container
+ZK1_IP=192.168.22.10
+ZK2_IP=192.168.22.11
+ZK3_IP=192.168.22.12
+
+# the Docker image
+ZK_IMAGE=jplock/zookeeper
+```
+
+Then create the containers:
+
+```
+ssh -n $ZK1_HOST "docker pull jplock/zookeeper && docker create --ip=$ZK1_IP --net netzksolr --name zk1 --hostname=zk1 --add-host zk2:$ZK2_IP --add-host zk3:$ZK3_IP -it $ZK_IMAGE"
+ssh -n $ZK2_HOST "docker pull jplock/zookeeper && docker create --ip=$ZK2_IP --net netzksolr --name zk2 --hostname=zk2 --add-host zk1:$ZK1_IP --add-host zk3:$ZK3_IP -it $ZK_IMAGE"
+ssh -n $ZK3_HOST "docker pull jplock/zookeeper && docker create --ip=$ZK3_IP --net netzksolr --name zk3 --hostname=zk3 --add-host zk1:$ZK1_IP --add-host zk2:$ZK2_IP -it $ZK_IMAGE"
+```
+
+Next configure those containers by creating ZooKeeper's `zoo.cfg` and `myid` files:
+
+```
+# Add ZooKeeper nodes to the ZooKeeper config.
+# If you use hostnames here, ZK will complain with UnknownHostException about the other nodes.
+# In ZooKeeper 3.4.6 that stays broken forever; in 3.4.7 that does recover.
+# If you use IP addresses you avoid the UnknownHostException and get a quorum more quickly,
+# but IP address changes can impact you.
+docker cp zk1:/opt/zookeeper/conf/zoo.cfg .
+cat >>zoo.cfg <<EOM
+server.1=zk1:2888:3888
+server.2=zk2:2888:3888
+server.3=zk3:2888:3888
+EOM
+
+cat zoo.cfg | ssh $ZK1_HOST 'dd of=zoo.cfg.tmp && docker cp zoo.cfg.tmp zk1:/opt/zookeeper/conf/zoo.cfg && rm zoo.cfg.tmp'
+cat zoo.cfg | ssh $ZK2_HOST 'dd of=zoo.cfg.tmp && docker cp zoo.cfg.tmp zk2:/opt/zookeeper/conf/zoo.cfg && rm zoo.cfg.tmp'
+cat zoo.cfg | ssh $ZK3_HOST 'dd of=zoo.cfg.tmp && docker cp zoo.cfg.tmp zk3:/opt/zookeeper/conf/zoo.cfg && rm zoo.cfg.tmp'
+rm zoo.cfg
+
+echo 1 | ssh $ZK1_HOST  'dd of=myid && docker cp myid zk1:/tmp/zookeeper/myid && rm myid'
+echo 2 | ssh $ZK2_HOST 'dd of=myid && docker cp myid zk2:/tmp/zookeeper/myid && rm myid'
+echo 3 | ssh $ZK3_HOST 'dd of=myid && docker cp myid zk3:/tmp/zookeeper/myid && rm myid'
+```
+
+Now start the containers:
+
+```
+ssh -n $ZK1_HOST 'docker start zk1'
+ssh -n $ZK2_HOST 'docker start zk2'
+ssh -n $ZK3_HOST 'docker start zk3'
+
+# Optional: verify containers are running
+ssh -n $ZK1_HOST 'docker ps'
+ssh -n $ZK2_HOST 'docker ps'
+ssh -n $ZK3_HOST 'docker ps'
+
+# Optional: inspect IP addresses of the containers
+ssh -n $ZK1_HOST "docker inspect --format '{{ .NetworkSettings.Networks.netzksolr.IPAddress }}' zk1"
+ssh -n $ZK2_HOST "docker inspect --format '{{ .NetworkSettings.Networks.netzksolr.IPAddress }}' zk2"
+ssh -n $ZK3_HOST "docker inspect --format '{{ .NetworkSettings.Networks.netzksolr.IPAddress }}' zk3"
+
+# Optional: verify connectivity and hostnames
+ssh -n $ZK1_HOST 'docker run --rm --net netzksolr -i ubuntu bash -c "echo -n zk1,zk2,zk3 | xargs -n 1 --delimiter=, /bin/ping -c 1"'
+ssh -n $ZK2_HOST 'docker run --rm --net netzksolr -i ubuntu bash -c "echo -n zk1,zk2,zk3 | xargs -n 1 --delimiter=, /bin/ping -c 1"'
+ssh -n $ZK3_HOST 'docker run --rm --net netzksolr -i ubuntu bash -c "echo -n zk1,zk2,zk3 | xargs -n 1 --delimiter=, /bin/ping -c 1"'
+
+# Optional: verify cluster got a leader
+ssh -n $ZK1_HOST "docker exec -i zk1 bash -c 'echo stat | nc localhost 2181'"
+ssh -n $ZK2_HOST "docker exec -i zk2 bash -c 'echo stat | nc localhost 2181'"
+ssh -n $ZK3_HOST "docker exec -i zk3 bash -c 'echo stat | nc localhost 2181'"
+
+# Optional: verify we can connect a zookeeper client. This should show the `[zookeeper]` znode.
+printf "ls /\nquit\n" | ssh $ZK1_HOST docker exec -i zk1 /opt/zookeeper/bin/zkCli.sh
+```
+
+That's the ZooKeeper cluster running.
+
+Next, we create Solr containers in much the same way:
+```
+ZKSOLR1_HOST=trinity10.lan
+ZKSOLR2_HOST=trinity20.lan
+ZKSOLR3_HOST=trinity30.lan
+
+ZKSOLR1_IP=192.168.22.20
+ZKSOLR2_IP=192.168.22.21
+ZKSOLR3_IP=192.168.22.22
+
+# the Docker image
+SOLR_IMAGE=solr
+
+HOST_OPTIONS="--add-host zk1:$ZK1_IP --add-host zk2:$ZK2_IP --add-host zk3:$ZK3_IP"
+ssh -n $ZKSOLR1_HOST "docker pull $SOLR_IMAGE && docker create --ip=$ZKSOLR1_IP --net netzksolr --name zksolr1 --hostname=zksolr1 -it $HOST_OPTIONS $SOLR_IMAGE"
+ssh -n $ZKSOLR2_HOST "docker pull $SOLR_IMAGE && docker create --ip=$ZKSOLR2_IP --net netzksolr --name zksolr2 --hostname=zksolr2 -it $HOST_OPTIONS $SOLR_IMAGE"
+ssh -n $ZKSOLR3_HOST "docker pull $SOLR_IMAGE && docker create --ip=$ZKSOLR3_IP --net netzksolr --name zksolr3 --hostname=zksolr3 -it $HOST_OPTIONS $SOLR_IMAGE"
+```
+
+Now configure Solr to know where its ZooKeeper cluster is, and start the containers:
+
+```
+for h in zksolr1 zksolr2 zksolr3; do
+  docker cp zksolr1:/opt/solr/bin/solr.in.sh .
+  sed -i -e 's/#ZK_HOST=""/ZK_HOST="zk1:2181,zk2:2181,zk3:2181"/' solr.in.sh
+  sed -i -e 's/#*SOLR_HOST=.*/SOLR_HOST="'$h'"/' solr.in.sh
+  mv solr.in.sh solr.in.sh-$h
+done
+cat solr.in.sh-zksolr1 | ssh $ZKSOLR1_HOST "dd of=solr.in.sh && docker cp solr.in.sh zksolr1:/opt/solr/bin/solr.in.sh && rm solr.in.sh"
+cat solr.in.sh-zksolr2 | ssh $ZKSOLR2_HOST "dd of=solr.in.sh && docker cp solr.in.sh zksolr2:/opt/solr/bin/solr.in.sh && rm solr.in.sh"
+cat solr.in.sh-zksolr3 | ssh $ZKSOLR3_HOST "dd of=solr.in.sh && docker cp solr.in.sh zksolr3:/opt/solr/bin/solr.in.sh && rm solr.in.sh"
+rm solr.in.sh*
+
+ssh -n $ZKSOLR1_HOST docker start zksolr1
+ssh -n $ZKSOLR2_HOST docker start zksolr2
+ssh -n $ZKSOLR3_HOST docker start zksolr3
+
+# Optional: print IP addresses to verify
+ssh -n $ZKSOLR1_HOST 'docker inspect --format "{{ .NetworkSettings.Networks.netzksolr.IPAddress }}" zksolr1'
+ssh -n $ZKSOLR2_HOST 'docker inspect --format "{{ .NetworkSettings.Networks.netzksolr.IPAddress }}" zksolr2'
+ssh -n $ZKSOLR3_HOST 'docker inspect --format "{{ .NetworkSettings.Networks.netzksolr.IPAddress }}" zksolr3'
+
+# Optional: check logs
+ssh -n $ZKSOLR1_HOST docker logs zksolr1
+ssh -n $ZKSOLR2_HOST docker logs zksolr2
+ssh -n $ZKSOLR3_HOST docker logs zksolr3
+
+# Optional: check the webserver
+ssh -n $ZKSOLR1_HOST "docker exec -i zksolr1 /bin/bash -c 'wget -O -  http://zksolr1:8983/'"
+ssh -n $ZKSOLR2_HOST "docker exec -i zksolr2 /bin/bash -c 'wget -O -  http://zksolr2:8983/'"
+ssh -n $ZKSOLR3_HOST "docker exec -i zksolr3 /bin/bash -c 'wget -O -  http://zksolr3:8983/'"
+```
+
+Next let's create a collection:
+
+```
+ssh -n $ZKSOLR1_HOST docker exec -i zksolr1 /opt/solr/bin/solr create_collection -c my_collection1 -shards 2 -p 8983
+```
+
+To load data, and see it was split over shards:
+
+```
+mak@trinity10:~$ docker exec -it --user=solr zksolr1 bin/post -c my_collection1 example/exampledocs/manufacturers.xml
+/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java -classpath /opt/solr/dist/solr-core-5.4.0.jar -Dauto=yes -Dc=my_collection1 -Ddata=files org.apache.solr.util.SimplePostTool example/exampledocs/manufacturers.xml
+SimplePostTool version 5.0.0
+Posting files to [base] url http://localhost:8983/solr/my_collection1/update...
+Entering auto mode. File endings considered are xml,json,csv,pdf,doc,docx,ppt,pptx,xls,xlsx,odt,odp,ods,ott,otp,ots,rtf,htm,html,txt,log
+POSTing file manufacturers.xml (application/xml) to [base]
+1 files indexed.
+COMMITting Solr index changes to http://localhost:8983/solr/my_collection1/update...
+Time spent: 0:00:01.093
+mak@trinity10:~$ docker exec -it --user=solr zksolr1 bash -c "wget -q -O - 'http://zksolr1:8983/solr/my_collection1/select?q=*:*&indent=true&rows=100&fl=id' | egrep '<str name=.id.>' |  wc -l"
+11
+mak@trinity10:~$ docker exec -it --user=solr zksolr1 bash -c "wget -q -O - 'http://zksolr1:8983/solr/my_collection1/select?q=*:*&shards=shard1&rows=100&indent=true&fl=id' | grep '<str name=.id.>' | wc -l"
+4
+mak@trinity10:~$ docker exec -it --user=solr zksolr1 bash -c "wget -q -O - 'http://zksolr1:8983/solr/my_collection1/select?q=*:*&shards=shard2&rows=100&indent=true&fl=id' | grep '<str name=.id.>' | wc -l"
+7
+```
+
+Now to get external access to this overlay network from outside we can use a container to proxy the connections.
+For a simple TCP proxy container with an exposed port on the Docker host, proxying to a single Solr node, you can use [brandnetworks/tcpproxy](https://github.com/brandnetworks/tcpproxy):
+
+```
+ssh -n trinity10.lan "docker pull brandnetworks/tcpproxy && docker run -p 8001 -p 8002 --net netzksolr --name zksolrproxy --hostname=zksolrproxy.netzksolr -tid brandnetworks/tcpproxy --connections 8002:zksolr1:8983"
+docker port zksolrproxy 8002
+```
+
+Or use a suitably configured HAProxy to round-robin between all Solr nodes. Or, instead of the overlay network, use [Project Calico](http://www.projectcalico.org) and configure L3 routing so you do not need to mess with proxies.
+
+Now I can get to Solr on http://trinity10:32774/solr/#/. In the Cloud -> Tree -> /live_nodes view I see the Solr nodes.
+
+From the Solr UI select the collection1 core, and click on Cloud -> Graph to see how it has created
+two shards across our Solr nodes.
+
+Now, by way of test, we'll stop the Solr containers, and start them out-of-order, and verify the IP addresses are unchanged, and check the same results come back:
+
+```
+ssh -n $ZKSOLR1_HOST docker kill zksolr1
+ssh -n $ZKSOLR2_HOST docker kill zksolr2
+ssh -n $ZKSOLR3_HOST docker kill zksolr3
+
+ssh -n $ZKSOLR1_HOST docker start zksolr1
+sleep 3
+ssh -n $ZKSOLR3_HOST docker start zksolr3
+sleep 3
+ssh -n $ZKSOLR2_HOST docker start zksolr2
+
+ssh -n $ZKSOLR1_HOST 'docker inspect --format "{{ .NetworkSettings.Networks.netzksolr.IPAddress }}" zksolr1'
+ssh -n $ZKSOLR2_HOST 'docker inspect --format "{{ .NetworkSettings.Networks.netzksolr.IPAddress }}" zksolr2'
+ssh -n $ZKSOLR3_HOST 'docker inspect --format "{{ .NetworkSettings.Networks.netzksolr.IPAddress }}" zksolr3'
+
+docker exec -it --user=solr zksolr1 bash -c "wget -q -O - 'http://zksolr1:8983/solr/my_collection1/select?q=*:*&indent=true&rows=100&fl=id' | egrep '<str name=.id.>' |  wc -l"
+docker exec -it --user=solr zksolr1 bash -c "wget -q -O - 'http://zksolr1:8983/solr/my_collection1/select?q=*:*&shards=shard1&rows=100&indent=true&fl=id' | grep '<str name=.id.>' | wc -l"
+docker exec -it --user=solr zksolr1 bash -c "wget -q -O - 'http://zksolr1:8983/solr/my_collection1/select?q=*:*&shards=shard2&rows=100&indent=true&fl=id' | grep '<str name=.id.>' | wc -l"
+```
+
+Good, that works.
+
+
+Finally To clean up this example:
+```
+ssh -n $ZK1_HOST "docker kill zk1; docker rm zk1"
+ssh -n $ZK2_HOST "docker kill zk2; docker rm zk2"
+ssh -n $ZK3_HOST "docker kill zk3; docker rm zk3"
+ssh -n $ZKSOLR1_HOST "docker kill zksolr1; docker rm zksolr1"
+ssh -n $ZKSOLR2_HOST "docker kill zksolr2; docker rm zksolr2"
+ssh -n $ZKSOLR3_HOST "docker kill zksolr3; docker rm zksolr3"
+ssh -n trinity10.lan "docker kill zksolrproxy; docker rm zksolrproxy"
+docker network rm netzksolr
+```
diff --git a/solr/docker/docs/precreate-collection.sh b/solr/docker/docs/precreate-collection.sh
new file mode 100644
index 0000000..a665966
--- /dev/null
+++ b/solr/docker/docs/precreate-collection.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+#
+# A script that creates a core by copying config before starting solr.
+#
+# To use this, map this file into your container's docker-entrypoint-initdb.d directory:
+#
+#     docker run -d -P -v $PWD/precreate-collection.sh:/docker-entrypoint-initdb.d/precreate-collection.sh solr
+
+CORE=${CORE:-gettingstarted}
+if [[ -d "/opt/solr/server/solr/$CORE" ]]; then
+    echo "$CORE is already present on disk"
+    exit 0
+fi
+
+mkdir -p "/opt/solr/server/solr/$CORE/"
+cd "/opt/solr/server/solr/$CORE" || exit
+touch core.properties
+# TODO: we may want a more minimal example here
+cp -r /opt/solr/example/files/* .
+echo created "/opt/solr/server/solr/$CORE"
diff --git a/solr/docker/docs/set-heap.sh b/solr/docker/docs/set-heap.sh
new file mode 100755
index 0000000..5755b0e
--- /dev/null
+++ b/solr/docker/docs/set-heap.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+#
+# This script is mainly an illustration for the docker-entrypoint-initdb.d extension mechanism.
+# Run it with e.g.:
+#
+#   docker run -d -P -v $PWD/docs/set-heap.sh:/docker-entrypoint-initdb.d/set-heap.sh solr
+#
+# The SOLR_HEAP configuration technique here is usable for older versions of Solr.
+# From Solr 6.3 setting the SOLR_HEAP can be done more easily with:
+#
+#   docker run -d -P -e SOLR_HEAP=800m apache/solr
+#
+set -e
+cp /opt/solr/bin/solr.in.sh /opt/solr/bin/solr.in.sh.orig
+sed -e 's/SOLR_HEAP=".*"/SOLR_HEAP="1024m"/' </opt/solr/bin/solr.in.sh.orig >/opt/solr/bin/solr.in.sh
+grep '^SOLR_HEAP=' /opt/solr/bin/solr.in.sh
diff --git a/solr/docker/include/scripts/docker-entrypoint.sh b/solr/docker/include/scripts/docker-entrypoint.sh
new file mode 100755
index 0000000..38e7c1c
--- /dev/null
+++ b/solr/docker/include/scripts/docker-entrypoint.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+#
+# docker-entrypoint for Solr docker
+
+set -e
+
+# Clear some variables that we don't want runtime
+unset SOLR_USER SOLR_UID SOLR_GROUP SOLR_GID \
+      SOLR_CLOSER_URL SOLR_DIST_URL SOLR_ARCHIVE_URL SOLR_DOWNLOAD_URL SOLR_DOWNLOAD_SERVER SOLR_KEYS SOLR_SHA512
+
+if [[ "$VERBOSE" == "yes" ]]; then
+    set -x
+fi
+
+if ! [[ ${SOLR_PORT:-} =~ ^[0-9]+$ ]]; then
+  SOLR_PORT=8983
+  export SOLR_PORT
+fi
+
+# when invoked with e.g.: docker run solr -help
+if [ "${1:0:1}" == '-' ]; then
+    set -- solr-foreground "$@"
+fi
+
+# execute command passed in as arguments.
+# The Dockerfile has specified the PATH to include
+# /opt/solr/bin (for Solr) and /opt/docker-solr/scripts (for our scripts
+# like solr-foreground, solr-create, solr-precreate, solr-demo).
+# Note: if you specify "solr", you'll typically want to add -f to run it in
+# the foreground.
+exec "$@"
diff --git a/solr/docker/include/scripts/init-var-solr b/solr/docker/include/scripts/init-var-solr
new file mode 100755
index 0000000..8a29de1
--- /dev/null
+++ b/solr/docker/include/scripts/init-var-solr
@@ -0,0 +1,61 @@
+#!/bin/bash
+#
+# A helper script to initialise an empty $DIR
+# If you use volumes then Docker will copy the $DIR content from the container to the volume.
+# If you use bind mounts, that does not happen, so we do it here.
+
+set -e
+
+if [[ "$VERBOSE" == "yes" ]]; then
+    set -x
+fi
+
+if [[ -n "${NO_INIT_VAR_SOLR:-}" ]]; then
+    exit 0
+fi
+
+DIR=${1:-/var/solr}
+
+if [ ! -d "$DIR" ]; then
+    echo "Missing $DIR"
+    exit 1
+fi
+
+function check_dir_writability {
+    local dir="$1"
+    if [ ! -w "$dir" ]; then
+        echo "Cannot write to $dir as $(id -u):$(id -g)"
+        ls -ld "$dir"
+        exit 1
+    fi
+}
+
+if [ ! -d "$DIR/data" ]; then
+    echo "Creating $DIR/data"
+    check_dir_writability "$DIR"
+    mkdir "$DIR/data"
+    chmod 0770 "$DIR/data"
+fi
+
+if [ ! -d "$DIR/logs" ]; then
+    echo "Creating $DIR/logs"
+    check_dir_writability "$DIR"
+    mkdir "$DIR/logs"
+    chmod 0770 "$DIR/logs"
+fi
+
+if [ ! -f "$DIR/data/solr.xml" ]; then
+    echo "Copying solr.xml"
+    cp -a /opt/solr/server/solr/solr.xml "$DIR/data/solr.xml"
+fi
+
+if [ ! -f "$DIR/data/zoo.cfg" ]; then
+    echo "Copying zoo.cfg"
+    cp -a /opt/solr/server/solr/zoo.cfg "$DIR/data/zoo.cfg"
+fi
+
+if [ ! -f "$DIR/log4j2.xml" ]; then
+    echo "Copying log4j2.xml"
+    cp -a /opt/solr/server/resources/log4j2.xml "$DIR/log4j2.xml"
+fi
+
diff --git a/solr/docker/include/scripts/oom_solr.sh b/solr/docker/include/scripts/oom_solr.sh
new file mode 100755
index 0000000..bed5095
--- /dev/null
+++ b/solr/docker/include/scripts/oom_solr.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+# Custom oom handler loosely based on
+# https://github.com/apache/lucene-solr/blob/master/solr/bin/oom_solr.sh
+# See solr-forgeground for how to configure OOM behaviour
+
+if [[ -z "${SOLR_LOGS_DIR:-}" ]]; then
+    if [ -d /var/solr/logs ]; then
+        SOLR_LOGS_DIR=/var/solr/logs
+    elif [ -d /opt/solr/server/logs ]; then
+        SOLR_LOGS_DIR=/opt/solr/server/logs
+    else
+        echo "Cannot determine SOLR_LOGS_DIR!"
+        exit 1
+    fi
+fi
+SOLR_PID=$(pgrep -f start.jar)
+if [[ -z "$SOLR_PID" ]]; then
+  echo "Couldn't find Solr process running!"
+  exit
+fi
+
+NOW=$(date +"%F_%H_%M_%S")
+(
+echo "Running OOM killer script for Solr process $SOLR_PID"
+if [[ "$SOLR_PID" == 1 ]]; then
+  # under Docker, when running as pid 1, a SIGKILL is ignored,
+  # so use the default SIGTERM
+  kill "$SOLR_PID"
+  sleep 2
+  # if that hasn't worked, send SIGKILL
+  kill -SIGILL "$SOLR_PID"
+else
+  # if we're running with `--init` or under tini or similar,
+  # follow the upstream behaviour
+  kill -9 "$SOLR_PID"
+fi
+) | tee "$SOLR_LOGS_DIR/solr_oom_killer-$SOLR_PORT-$NOW.log"
diff --git a/solr/docker/include/scripts/precreate-core b/solr/docker/include/scripts/precreate-core
new file mode 100755
index 0000000..bca0f48
--- /dev/null
+++ b/solr/docker/include/scripts/precreate-core
@@ -0,0 +1,40 @@
+#!/bin/bash
+#
+# Create a core on disk
+# arguments are: corename configdir
+
+set -e
+
+echo "Executing $0" "$@"
+
+if [[ "${VERBOSE:-}" == "yes" ]]; then
+    set -x
+fi
+
+CORE=${1:-gettingstarted}
+CONFIG_SOURCE="${2:-}"
+if [[ -z "$CONFIG_SOURCE" ]]; then
+    DEFAULT_CONFIGS=(_default data_driven_schema_configs)
+    for config_dir in "${DEFAULT_CONFIGS[@]}"; do
+        config_dir="/opt/solr/server/solr/configsets/$config_dir"
+        if [ -d "$config_dir" ]; then
+           CONFIG_SOURCE="$config_dir"
+           break
+        fi
+    done
+    if [[ -z $CONFIG_SOURCE ]]; then
+        echo "Cannot find default config"
+        exit 1
+    fi
+fi
+
+coresdir=/var/solr/data
+
+coredir="$coresdir/$CORE"
+if [[ ! -d $coredir ]]; then
+    cp -r "$CONFIG_SOURCE/" "$coredir"
+    touch "$coredir/core.properties"
+    echo "Created $CORE"
+else
+    echo "Core $CORE already exists"
+fi
diff --git a/solr/docker/include/scripts/run-initdb b/solr/docker/include/scripts/run-initdb
new file mode 100755
index 0000000..5f250c9
--- /dev/null
+++ b/solr/docker/include/scripts/run-initdb
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+# Run the init-solr-home script and source any '.sh' scripts in
+# /docker-entrypoint-initdb.d.
+# This script is sourced by some of the solr-* commands, so that
+# you can run eg:
+#
+#   mkdir initdb; echo "echo hi" > initdb/hi.sh
+#   docker run -v $PWD/initdb:/docker-entrypoint-initdb.d solr
+#
+# and have your script execute before Solr starts.
+#
+# Note: scripts can modify the environment, which will affect
+# subsequent scripts and ultimately Solr. That allows you to set
+# environment variables from your scripts (though you usually just
+# use "docker run -e"). If this is undesirable in your use-case,
+# have your scripts execute a sub-shell.
+
+set -e
+
+# execute files in /docker-entrypoint-initdb.d before starting solr
+while read -r f; do
+    case "$f" in
+        *.sh)     echo "$0: running $f"; . "$f" ;;
+        *)        echo "$0: ignoring $f" ;;
+    esac
+    echo
+done < <(find /docker-entrypoint-initdb.d/ -mindepth 1 -type f | sort -n)
diff --git a/solr/docker/include/scripts/solr-create b/solr/docker/include/scripts/solr-create
new file mode 100755
index 0000000..e2054a1
--- /dev/null
+++ b/solr/docker/include/scripts/solr-create
@@ -0,0 +1,66 @@
+#!/bin/bash
+#
+# This script starts Solr on localhost, creates a core with "solr create",
+# stops Solr, and then starts Solr as normal.
+# Any arguments are passed to the "solr create".
+# To simply create a core:
+#      docker run -P -d solr solr-create -c mycore
+# To create a core from mounted config:
+#      docker run -P -d -v $PWD/myconfig:/myconfig solr solr-create -c mycore -d /myconfig
+
+set -euo pipefail
+echo "Executing $0" "$@"
+
+if [[ "${VERBOSE:-}" == "yes" ]]; then
+    set -x
+fi
+
+# init script for handling an empty /var/solr
+/opt/docker-solr/scripts/init-var-solr
+
+. /opt/docker-solr/scripts/run-initdb
+
+# solr uses "-c corename". Parse the arguments to determine the core name.
+CORE_NAME="$(
+  while (( $# > 0 )); do
+    if [[ "$1" == '-c' ]]; then
+      shift
+      echo "$1"
+    fi
+    shift
+  done
+)"
+if [[ -z "${CORE_NAME:-}" ]]; then
+  echo "Could not determine core name"
+  exit 1
+fi
+
+coresdir=/var/solr/data
+CORE_DIR="$coresdir/$CORE_NAME"
+
+if [[ -d $CORE_DIR ]]; then
+    echo "Directory $CORE_DIR exists; skipping core creation"
+else
+    start-local-solr
+
+    echo "Creating core with:" "${@:1}"
+    /opt/solr/bin/solr create "${@:1}"
+
+    # See https://github.com/docker-solr/docker-solr/issues/27
+    echo "Checking core"
+    if ! wget -O - "http://localhost:${SOLR_PORT:-8983}/solr/admin/cores?action=STATUS" | grep instanceDir >/dev/null; then
+      echo "Could not find any cores"
+      exit 1
+    fi
+
+    echo "Created core with:" "${@:1}"
+    stop-local-solr
+
+    # check the core_dir exists; otherwise the detecting above will fail after stop/start
+    if [ ! -d "$CORE_DIR" ]; then
+        echo "Missing $CORE_DIR"
+        exit 1
+    fi
+fi
+
+exec solr-fg
diff --git a/solr/docker/include/scripts/solr-demo b/solr/docker/include/scripts/solr-demo
new file mode 100755
index 0000000..7d09d39
--- /dev/null
+++ b/solr/docker/include/scripts/solr-demo
@@ -0,0 +1,42 @@
+#!/bin/bash
+#
+# Configure a Solr demo and then run solr in the foreground
+
+set -euo pipefail
+
+if [[ "${VERBOSE:-}" == "yes" ]]; then
+    set -x
+fi
+
+. /opt/docker-solr/scripts/run-initdb
+
+CORE=demo
+
+coresdir=/var/solr/data
+CORE_DIR="$coresdir/demo"
+if [ -d "$CORE_DIR" ]; then
+  echo "$CORE_DIR exists; skipping demo creation"
+else
+  start-local-solr
+  echo "Creating $CORE"
+  /opt/solr/bin/solr create -c "$CORE"
+  echo "Created $CORE"
+  echo "Loading example data"
+  post_args=()
+  if [[ -n "${SOLR_PORT:-}" ]]; then
+    post_args+=(-p "$SOLR_PORT")
+  fi
+  /opt/solr/bin/post "${post_args[@]}" -c $CORE -commit no example/exampledocs/*.xml
+  /opt/solr/bin/post "${post_args[@]}" -c $CORE -commit no example/exampledocs/books.json
+  /opt/solr/bin/post "${post_args[@]}" -c $CORE -commit yes example/exampledocs/books.csv
+  echo "Loaded example data"
+  stop-local-solr
+
+    # check the core_dir exists; otherwise the detecting above will fail after stop/start
+    if [ ! -d "$CORE_DIR" ]; then
+        echo "Missing $CORE_DIR"
+        exit 1
+    fi
+fi
+
+exec solr-fg
diff --git a/solr/docker/include/scripts/solr-fg b/solr/docker/include/scripts/solr-fg
new file mode 100755
index 0000000..5501159
--- /dev/null
+++ b/solr/docker/include/scripts/solr-fg
@@ -0,0 +1,56 @@
+#!/bin/bash
+#
+# start solr in the foreground
+set -e
+
+if [[ "$VERBOSE" == "yes" ]]; then
+    set -x
+fi
+
+EXTRA_ARGS=()
+
+# Allow easy setting of the OOM behaviour
+# Test with: docker run -p 8983:8983 -it -e OOM=script -e SOLR_JAVA_MEM="-Xms25m -Xmx25m" solr
+if [[ -z "${OOM:-}" ]]; then
+  OOM='none'
+fi
+case "$OOM" in
+  'script')
+    EXTRA_ARGS+=(-a '-XX:OnOutOfMemoryError=/opt/docker-solr/scripts/oom_solr.sh')
+    ;;
+  'exit')
+    # recommended
+    EXTRA_ARGS+=(-a '-XX:+ExitOnOutOfMemoryError')
+    ;;
+  'crash')
+    EXTRA_ARGS+=(-a '-XX:+CrashOnOutOfMemoryError')
+    ;;
+  'none'|'')
+    ;;
+  *)
+   echo "Unsupported value in OOM=$OOM"
+   exit 1
+esac
+
+echo "Starting Solr $SOLR_VERSION"
+# determine TINI default. If it is already set, assume the user knows what they want
+if [[ -z "${TINI:-}" ]]; then
+  if [[ "$$" == 1 ]]; then
+    # Default to running tini, so we can run with an OOM script and have 'kill -9' work
+    TINI=yes
+  else
+    # Presumably we're already running under tini through 'docker --init', in which case we
+    # don't need to run it twice.
+    # It's also possible that we're run from a wrapper script without exec,
+    # in which case running tini would not be ideal either.
+    TINI=no
+  fi
+fi
+if [[ "$TINI" == yes ]]; then
+  exec tini -- solr -f "$@" "${EXTRA_ARGS[@]}"
+elif [[ "$TINI" == no ]]; then
+  exec solr -f "$@" "${EXTRA_ARGS[@]}"
+else
+  echo "invalid value TINI=$TINI"
+  exit 1
+fi
diff --git a/solr/docker/include/scripts/solr-foreground b/solr/docker/include/scripts/solr-foreground
new file mode 100755
index 0000000..336104b
--- /dev/null
+++ b/solr/docker/include/scripts/solr-foreground
@@ -0,0 +1,15 @@
+#!/bin/bash
+#
+# Run the initdb, then start solr in the foreground
+set -e
+
+if [[ "$VERBOSE" == "yes" ]]; then
+    set -x
+fi
+
+# init script for handling an empty /var/solr
+/opt/docker-solr/scripts/init-var-solr
+
+. /opt/docker-solr/scripts/run-initdb
+
+exec solr-fg "$@"
diff --git a/solr/docker/include/scripts/solr-precreate b/solr/docker/include/scripts/solr-precreate
new file mode 100755
index 0000000..5248203
--- /dev/null
+++ b/solr/docker/include/scripts/solr-precreate
@@ -0,0 +1,27 @@
+#!/bin/bash
+#
+# Create a core on disk and then run solr in the foreground
+# arguments are: corename configdir
+# To simply create a core:
+#      docker run -P -d solr solr-precreate mycore
+# To create a core from mounted config:
+#      docker run -P -d -v $PWD/myconfig:/myconfig solr solr-precreate mycore /myconfig
+# To create a core in a mounted directory:
+#      mkdir myvarsolr; chown 8983:8983 myvarsolr
+#      docker run -it --rm -P -v $PWD/myvarsolr://var/solr solr solr-precreate mycore
+set -e
+
+echo "Executing $0" "$@"
+
+if [[ "${VERBOSE:-}" == "yes" ]]; then
+    set -x
+fi
+
+# init script for handling an empty /var/solr
+/opt/docker-solr/scripts/init-var-solr
+
+. /opt/docker-solr/scripts/run-initdb
+
+/opt/docker-solr/scripts/precreate-core "$@"
+
+exec solr-fg
diff --git a/solr/docker/include/scripts/start-local-solr b/solr/docker/include/scripts/start-local-solr
new file mode 100755
index 0000000..50edf13
--- /dev/null
+++ b/solr/docker/include/scripts/start-local-solr
@@ -0,0 +1,21 @@
+#!/bin/bash
+# configure Solr to run on the local interface, and start it running in the background
+
+set -euo pipefail
+
+if [[ "${VERBOSE:-}" == "yes" ]]; then
+    set -x
+fi
+
+echo "Running solr in the background. Logs are in /var/solr/logs"
+SOLR_OPTS="-Djetty.host=${SOLR_LOCAL_HOST:-localhost}" solr start
+max_try=${MAX_TRY:-12}
+wait_seconds=${WAIT_SECONDS:-5}
+if ! /opt/docker-solr/scripts/wait-for-solr.sh --max-attempts "$max_try" --wait-seconds "$wait_seconds"; then
+    echo "Could not start Solr."
+    if [ -f "/var/solr/logs/solr.log" ]; then
+        echo "Here is the log:"
+        cat "/var/solr/logs/solr.log"
+    fi
+    exit 1
+fi
diff --git a/solr/docker/include/scripts/stop-local-solr b/solr/docker/include/scripts/stop-local-solr
new file mode 100755
index 0000000..a0c7742
--- /dev/null
+++ b/solr/docker/include/scripts/stop-local-solr
@@ -0,0 +1,11 @@
+#!/bin/bash
+# stop the background Solr, and restore the normal configuration
+
+set -e
+
+if [[ "$VERBOSE" == "yes" ]]; then
+    set -x
+fi
+
+echo "Shutting down the background Solr"
+solr stop
diff --git a/solr/docker/include/scripts/wait-for-solr.sh b/solr/docker/include/scripts/wait-for-solr.sh
new file mode 100755
index 0000000..aa9e15e
--- /dev/null
+++ b/solr/docker/include/scripts/wait-for-solr.sh
@@ -0,0 +1,98 @@
+#!/bin/bash
+#
+# A helper script to wait for solr
+#
+# Usage: wait-for-solr.sh [--max-attempts count] [--wait-seconds seconds] [--solr-url url]
+# Deprecated usage: wait-for-solr.sh [ max_attempts [ wait_seconds ] ]
+
+set -euo pipefail
+
+SCRIPT="$0"
+
+if [[ "${VERBOSE:-}" == "yes" ]]; then
+    set -x
+fi
+
+function usage {
+  echo "$1"
+  echo "Usage: $SCRIPT [--max-attempts count] [--wait-seconds seconds ] [--solr-url url]"
+  exit 1
+}
+
+max_attempts=12
+wait_seconds=5
+
+if ! [[ ${SOLR_PORT:-8983} =~ ^[0-9]+$ ]]; then
+  echo "Invalid SOLR_PORT=${SOLR_PORT:-} environment variable specified"
+  exit 1
+fi
+
+solr_url="http://localhost:${SOLR_PORT:-8983}"
+
+while (( $# > 0 )); do
+  case "$1" in
+   --help)
+     cat <<EOM
+Usage: $SCRIPT [options]
+
+Options:
+  --max-attempts count: number of attempts to check Solr is up. Default: $max_attempts
+  --wait-seconds seconds: number of seconds to wait between attempts. Default: $wait_seconds
+  --solr-url url: URL for Solr server to check. Default: $solr_url
+EOM
+     exit 0
+     ;;
+   --solr-url)
+     solr_url="$2";
+     shift 2
+     ;;
+
+   --max-attempts)
+     max_attempts="$2";
+     shift 2;
+     ;;
+
+   --wait-seconds)
+     wait_seconds="$2";
+     shift 2;
+     ;;
+
+  * )
+    # deprecated invocation, kept for backwards compatibility
+    max_attempts=$1;
+    wait_seconds=$2;
+    echo "WARNING: deprecated invocation. Use $SCRIPT [--max-attempts count] [--wait-seconds seconds]"
+    shift 2;
+    break;
+    ;;
+
+  esac
+done
+
+grep -q -E '^[0-9]+$' <<<"$max_attempts" || usage "--max-attempts $max_attempts: not a number"
+if (( max_attempts == 0 )); then
+  echo "The --max-attempts argument should be >0"
+  exit 1
+fi
+grep -q -E '^[0-9]+$' <<<"$wait_seconds" || usage "--wait-seconds $wait_seconds: not a number"
+grep -q -E '^https?://' <<<"$solr_url" || usage "--solr-url $solr_url: not a URL"
+
+((attempts_left=max_attempts))
+while (( attempts_left > 0 )); do
+  if wget -q -O - "$solr_url" | grep -i solr >/dev/null; then
+    break
+  fi
+  (( attempts_left-- ))
+  if (( attempts_left == 0 )); then
+    echo "Solr is still not running; giving up"
+    exit 1
+  fi
+  if (( attempts_left == 1 )); then
+    attempts=attempt
+  else
+    attempts=attempts
+  fi
+  echo "Solr is not running yet on $solr_url. $attempts_left $attempts left"
+  sleep "$wait_seconds"
+done
+echo "Solr is running on $solr_url"
diff --git a/solr/docker/include/scripts/wait-for-zookeeper.sh b/solr/docker/include/scripts/wait-for-zookeeper.sh
new file mode 100755
index 0000000..82366a4
--- /dev/null
+++ b/solr/docker/include/scripts/wait-for-zookeeper.sh
@@ -0,0 +1,165 @@
+#!/bin/bash
+#
+# A helper script to wait for ZooKeeper
+#
+# This script waits for a ZooKeeper master to appear.
+# It repeatedly looks up the name passed as argument
+# in the DNS using getent, and then connects to the
+# ZooKeeper admin port and uses the 'srvr' command to
+# obtain the server's status.
+# You can use this in a Kubernetes init container to
+# delay Solr pods starting until the ZooKeeper service
+# has settled down. Or you could explicitly run this in
+# the Solr container before exec'ing Solr.
+#
+# Inspired by https://github.com/helm/charts/blob/9eba7b1c80990233a68dce48f4a8fe0baf9b7fa5/incubator/solr/templates/statefulset.yaml#L60
+#
+# Usage: wait-for-zookeeper.sh [--max-attempts count] [--wait-seconds seconds] zookeeper-service-name
+#
+# If no argument is provided, but a Solr-style ZK_HOST is set,
+# that will be used. If neither is provided, the default
+# name is 'solr-zookeeper-headless', to match the helm chart.
+
+set -euo pipefail
+
+SCRIPT="$0"
+
+if [[ "${VERBOSE:-}" == "yes" ]]; then
+    set -x
+fi
+
+function usage {
+  echo "$1"
+  echo "Usage: $SCRIPT [--max-attempts count] [--wait-seconds seconds ] zookeeper-service-name"
+  exit 1
+}
+
+TMP_HOSTS="/tmp/hosts.$$"
+TMP_STATUS="/tmp/status.$$"
+
+function cleanup {
+    rm -f $TMP_HOSTS $TMP_STATUS
+}
+
+trap cleanup EXIT
+
+function check_zookeeper {
+    local host=$1
+    local port="${2:-2181}"
+    if ! echo srvr | nc "$host" "$port" > $TMP_STATUS; then
+        echo "Failed to get status from $host"
+        return
+    fi
+    if [ ! -s $TMP_STATUS ]; then
+        echo "No data from $ip"
+        return
+    fi
+    if grep -q 'not currently serving requests' $TMP_STATUS; then
+        echo "Node $ip is not currently serving requests"
+        return
+    fi
+    mode=$(grep "Mode: " $TMP_STATUS | sed 's/Mode: //');
+    if [ -z "$mode" ]; then
+        echo "Cannot determine mode from:"
+        cat $TMP_STATUS
+        return
+    fi
+    echo "Node $ip is a $mode"
+    if [ "$mode" = "leader" ] || [ "$mode" = "standalone" ]; then
+        echo "Done"
+        exit 0
+    fi
+}
+
+max_attempts=120
+wait_seconds=2
+while (( $# > 0 )); do
+  case "$1" in
+   --help)
+     cat <<EOM
+Usage: $SCRIPT [options] zookeeper-service-name
+
+Options:
+  --max-attempts count: number of attempts to check Solr is up. Default: $max_attempts
+  --wait-seconds seconds: number of seconds to wait between attempts. Default: $wait_seconds
+EOM
+     exit 0
+     ;;
+
+   --max-attempts)
+     max_attempts="$2";
+     shift 2;
+     ;;
+
+   --wait-seconds)
+     wait_seconds="$2";
+     shift 2;
+     ;;
+
+   *)
+    if [ -n "${lookup_arg:-}" ]; then
+      usage "Cannot specify multiple zookeeper service names"
+    fi
+    lookup_arg=$1;
+    shift;
+    break;
+    ;;
+
+  esac
+done
+
+grep -q -E '^[0-9]+$' <<<"$max_attempts" || usage "--max-attempts $max_attempts: not a number"
+if (( max_attempts == 0 )); then
+  echo "The --max-attempts argument should be >0"
+  exit 1
+fi
+grep -q -E '^[0-9]+$' <<<"$wait_seconds" || usage "--wait-seconds $wait_seconds: not a number"
+
+if [ -z "${lookup_arg:-}" ]; then
+  if [ -n "$ZK_HOST" ]; then
+    lookup_arg="$ZK_HOST"
+  else
+    lookup_arg=solr-zookeeper-headless
+  fi
+fi
+
+echo "Looking up '$lookup_arg'"
+# split on commas, for when a ZK_HOST string like zoo1:2181,zoo2:2181 is used
+IFS=',' read -ra lookups <<< "$lookup_arg"
+((attempts_left=max_attempts))
+while (( attempts_left > 0 )); do
+  for lookup in "${lookups[@]}"; do
+    if grep -q -E "^\[[0-9].*\]" <<<"$lookup"; then
+      # looks like an IPv6 address, eg [2001:DB8::1] or [2001:DB8::1]:2181
+      # getent does not support the bracket notation, but does support IPv6 addresses
+      host=$(sed -E 's/\[(.*)\].*/\1/' <<<"$lookup")
+      port=$(sed -E 's/^\[(.*)\]:?//' <<<"$lookup")
+    else
+      # IPv4, just split on :
+      IFS=: read -ra split <<<"$lookup"
+      host="${split[0]}"
+      port="${split[1]:-}"
+    fi
+    if [[ "${VERBOSE:-}" == "yes" ]]; then
+      echo "Parsed host=$host port=${port:-}"
+    fi
+    if getent hosts "$host" > $TMP_HOSTS; then
+      while read -r ip hostname ; do
+        echo "${hostname:-}">/dev/null # consume for shellcheck
+        check_zookeeper "$ip" "$port"
+      done <$TMP_HOSTS
+    else
+      echo "Cannot find $lookup yet"
+    fi
+  done
+  (( attempts_left-- ))
+  if (( attempts_left == 0 )); then echo "Still no master found; giving up"
+    exit 1
+  fi
+  sleep "$wait_seconds"
+done
+
+# To test the parsing:
+#  bash scripts/wait-for-zookeeper.sh foo
+#  bash scripts/wait-for-zookeeper.sh 'ZK_HOST=[2001:DB8::1]:2181,[2001:DB8::1],127.0.0.1:2181,127.0.0.2'
+#  ZK_HOST=[2001:DB8::1]:2181,[2001:DB8::1],127.0.0.1:2181,127.0.0.2 bash scripts/wait-for-zookeeper.sh
diff --git a/solr/docker/package/Dockerfile.local-package b/solr/docker/package/Dockerfile.local-package
new file mode 100644
index 0000000..e37d67f
--- /dev/null
+++ b/solr/docker/package/Dockerfile.local-package
@@ -0,0 +1,3 @@
+FROM scratch
+
+COPY releases/ /opt/
\ No newline at end of file
diff --git a/solr/docker/package/Dockerfile.release-package b/solr/docker/package/Dockerfile.release-package
new file mode 100644
index 0000000..85947c9
--- /dev/null
+++ b/solr/docker/package/Dockerfile.release-package
@@ -0,0 +1,74 @@
+ARG BASE_IMAGE=openjdk:11-jre
+
+FROM $BASE_IMAGE as downloader
+
+ARG SOLR_VERSION
+ARG SOLR_SHA512
+ARG SOLR_KEYS
+# If specified, this will override SOLR_DOWNLOAD_SERVER and all ASF mirrors. Typically used downstream for custom builds
+ARG SOLR_DOWNLOAD_URL
+
+# Override the solr download location with e.g.:
+#   docker build -t mine --build-arg SOLR_DOWNLOAD_SERVER=http://www-eu.apache.org/dist/lucene/solr .
+ARG SOLR_DOWNLOAD_SERVER
+# This is only applicable when SOLR_DOWNLOAD_URL is not provided. Skips the GPG check for Solr downloads.
+ARG SKIP_GPG_CHECK="true"
+
+ENV SOLR_CLOSER_URL="http://www.apache.org/dyn/closer.lua?filename=lucene/solr/$SOLR_VERSION/solr-$SOLR_VERSION.tgz&action=download" \
+    SOLR_DIST_URL="https://www.apache.org/dist/lucene/solr/$SOLR_VERSION/solr-$SOLR_VERSION.tgz" \
+    SOLR_ARCHIVE_URL="https://archive.apache.org/dist/lucene/solr/$SOLR_VERSION/solr-$SOLR_VERSION.tgz"
+
+RUN set -ex; \
+    apt-get update; \
+    apt-get -y install dirmngr gpg wget; \
+    rm -rf /var/lib/apt/lists/*;
+
+RUN set -ex; \
+  export GNUPGHOME="/tmp/gnupg_home"; \
+  mkdir -p "$GNUPGHOME"; \
+  chmod 700 "$GNUPGHOME"; \
+  echo "disable-ipv6" >> "$GNUPGHOME/dirmngr.conf"; \
+  for key in $SOLR_KEYS; do \
+    found=''; \
+    for server in \
+      ha.pool.sks-keyservers.net \
+      hkp://keyserver.ubuntu.com:80 \
+      hkp://p80.pool.sks-keyservers.net:80 \
+      pgp.mit.edu \
+    ; do \
+      echo "  trying $server for $key"; \
+      gpg --batch --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$key" && found=yes && break; \
+      gpg --batch --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$key" && found=yes && break; \
+    done; \
+    test -z "$found" && echo >&2 "error: failed to fetch $key from several disparate servers -- network issues?" && exit 1; \
+  done; \
+  exit 0
+
+RUN set -ex; \
+  export GNUPGHOME="/tmp/gnupg_home"; \
+  MAX_REDIRECTS=1; \
+  if [ -n "$SOLR_DOWNLOAD_URL" ]; then \
+    # If a custom URL is defined, we download from non-ASF mirror URL and allow more redirects and skip GPG step
+    # This takes effect only if the SOLR_DOWNLOAD_URL build-arg is specified, typically in downstream Dockerfiles
+    MAX_REDIRECTS=4; \
+    SKIP_GPG_CHECK="true"; \
+  elif [ -n "$SOLR_DOWNLOAD_SERVER" ]; then \
+    SOLR_DOWNLOAD_URL="$SOLR_DOWNLOAD_SERVER/$SOLR_VERSION/solr-$SOLR_VERSION.tgz"; \
+  fi; \
+  for url in $SOLR_DOWNLOAD_URL $SOLR_CLOSER_URL $SOLR_DIST_URL $SOLR_ARCHIVE_URL; do \
+    if [ -f "/opt/solr-$SOLR_VERSION.tgz" ]; then break; fi; \
+    echo "downloading $url"; \
+    if wget -t 10 --max-redirect $MAX_REDIRECTS --retry-connrefused -nv "$url" -O "/opt/solr-$SOLR_VERSION.tgz"; then break; else rm -f "/opt/solr-$SOLR_VERSION.tgz"; fi; \
+  done; \
+  if [ ! -f "/opt/solr-$SOLR_VERSION.tgz" ]; then echo "failed all download attempts for solr-$SOLR_VERSION.tgz"; exit 1; fi; \
+  if [ "$SKIP_GPG_CHECK" != "true" ]; then \
+    echo "downloading $SOLR_ARCHIVE_URL.asc"; \
+    wget -nv "$SOLR_ARCHIVE_URL.asc" -O "/opt/solr-$SOLR_VERSION.tgz.asc"; \
+    echo "$SOLR_SHA512 */opt/solr-$SOLR_VERSION.tgz" | sha512sum -c -; \
+    (>&2 ls -l "/opt/solr-$SOLR_VERSION.tgz" "/opt/solr-$SOLR_VERSION.tgz.asc"); \
+    gpg --batch --verify "/opt/solr-$SOLR_VERSION.tgz.asc" "/opt/solr-$SOLR_VERSION.tgz"; \
+  else \
+    echo "Skipping GPG validation due to non-Apache build"; \
+  fi; \
+  { command -v gpgconf; gpgconf --kill all || :; }; \
+  rm -r "$GNUPGHOME";
diff --git a/solr/docker/package/build.gradle b/solr/docker/package/build.gradle
new file mode 100644
index 0000000..94cbfdb
--- /dev/null
+++ b/solr/docker/package/build.gradle
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+description = 'Solr Docker Package image'
+
+// The solr package docker image relies on the output of the solr:packaging project.
+Project solrPackaging = project(':solr:packaging')
+
+dependencies {
+  docker solrPackaging
+}
+
+docker {
+  name = 'apache/solr-build:local-package'
+  dockerfile file('Dockerfile.local-package')
+  files(solrPackaging.tasks.distTar.outputs)
+  getCopySpec().into('releases')
+}
+
+// Only allow the following docker tasks
+def availableDockerTasks = ["docker", "dockerClean", "dockerPrepare", "dockerfileZip"]
+project.tasks.configureEach { t -> t.enabled = t.getGroup() != "Docker" || availableDockerTasks.contains(t.getName()) }
diff --git a/solr/docker/tests/README.md b/solr/docker/tests/README.md
new file mode 100644
index 0000000..abb3a70
--- /dev/null
+++ b/solr/docker/tests/README.md
@@ -0,0 +1,6 @@
+
+To run tests, specify a fully-versioned image tag:
+
+```
+./test.sh apache/solr:6.6.0
+```
diff --git a/solr/docker/tests/cases/create_bad_core/test.sh b/solr/docker/tests/cases/create_bad_core/test.sh
new file mode 100755
index 0000000..b27b02c
--- /dev/null
+++ b/solr/docker/tests/cases/create_bad_core/test.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+echo "Running $container_name"
+if docker run --name "$container_name" "$tag" solr-create -c 'bad/core?name:here'; then
+  echo "Bad core creation did not return a failure"
+  exit 1
+fi
+
+container_cleanup "$container_name"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/create_core/test.sh b/solr/docker/tests/cases/create_core/test.sh
new file mode 100755
index 0000000..7a0c7e1
--- /dev/null
+++ b/solr/docker/tests/cases/create_core/test.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+echo "Running $container_name"
+docker run --name "$container_name" -d "$tag" solr-create -c gettingstarted
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c gettingstarted example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/gettingstarted/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+container_cleanup "$container_name"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/create_core_exec/test.sh b/solr/docker/tests/cases/create_core_exec/test.sh
new file mode 100755
index 0000000..31dfb68
--- /dev/null
+++ b/solr/docker/tests/cases/create_core_exec/test.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+echo "Running $container_name"
+docker run --name "$container_name" -d "$tag"
+
+wait_for_container_and_solr "$container_name"
+
+echo "Creating core"
+docker exec --user=solr "$container_name" bin/solr create_core -c gettingstarted
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c gettingstarted example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/gettingstarted/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+container_cleanup "$container_name"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/create_core_randomuser_rootgroup/test.sh b/solr/docker/tests/cases/create_core_randomuser_rootgroup/test.sh
new file mode 100755
index 0000000..1327d5f
--- /dev/null
+++ b/solr/docker/tests/cases/create_core_randomuser_rootgroup/test.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+#
+# Simulate openshift by running with a random uid
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+echo "Running $container_name"
+docker run --user 7777:0 --name "$container_name" -d "$tag" solr-create -c gettingstarted
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c gettingstarted example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/gettingstarted/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+
+
+docker exec --user=root "$container_name" ls -lR /var/solr
+
+container_cleanup "$container_name"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/demo-tini/test.sh b/solr/docker/tests/cases/demo-tini/test.sh
new file mode 100755
index 0000000..c4c142a
--- /dev/null
+++ b/solr/docker/tests/cases/demo-tini/test.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+echo "Running $container_name"
+docker run --name "$container_name" -d -e TINI=yes "$tag" "solr-demo"
+
+wait_for_container_and_solr "$container_name"
+
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/demo/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+
+data=$(docker exec --user=solr "$container_name" pgrep tini)
+echo "$data"
+
+container_cleanup "$container_name"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/demo/test.sh b/solr/docker/tests/cases/demo/test.sh
new file mode 100755
index 0000000..ca8d10f
--- /dev/null
+++ b/solr/docker/tests/cases/demo/test.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+echo "Running $container_name"
+docker run --name "$container_name" -d "$tag" "solr-demo"
+
+wait_for_container_and_solr "$container_name"
+
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/demo/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+container_cleanup "$container_name"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/empty-varsolr-dir-ramdomuser-rootgroup/test.sh b/solr/docker/tests/cases/empty-varsolr-dir-ramdomuser-rootgroup/test.sh
new file mode 100755
index 0000000..be6ef9f
--- /dev/null
+++ b/solr/docker/tests/cases/empty-varsolr-dir-ramdomuser-rootgroup/test.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+container_cleanup "$container_name-copier"
+
+myvarsolr="${BUILD_DIR}/myvarsolr-${container_name}"
+prepare_dir_to_mount 7777 "$myvarsolr"
+
+echo "Running $container_name"
+docker run \
+  --user 7777:0 \
+  -v "$myvarsolr:/var/solr" \
+  --name "$container_name" \
+  -d "$tag" solr-precreate getting-started
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c getting-started example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/getting-started/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+
+docker exec --user=7777 "$container_name" ls -l /var/solr/data
+
+container_cleanup "$container_name"
+
+# remove the solr-owned files from inside a container
+docker run --rm -e VERBOSE=yes \
+  --user root \
+  -v "$myvarsolr:/myvarsolr" "$tag" \
+  bash -c "rm -fr /myvarsolr/*"
+
+rm -fr "$myvarsolr"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/empty-varsolr-dir-solr/test.sh b/solr/docker/tests/cases/empty-varsolr-dir-solr/test.sh
new file mode 100755
index 0000000..9813f57
--- /dev/null
+++ b/solr/docker/tests/cases/empty-varsolr-dir-solr/test.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+container_cleanup "$container_name-copier"
+
+myvarsolr="${BUILD_DIR}/myvarsolr-${container_name}"
+prepare_dir_to_mount 8983 "$myvarsolr"
+
+echo "Running $container_name"
+docker run \
+  -v "$myvarsolr:/var/solr" \
+  --name "$container_name" \
+  -d "$tag" solr-precreate getting-started
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c getting-started example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/getting-started/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+
+docker exec --user=solr "$container_name" ls -l /var/solr/data
+
+container_cleanup "$container_name"
+
+ls -l "$myvarsolr"/
+
+# remove the solr-owned files from inside a container
+docker run --rm -e VERBOSE=yes \
+  -v "$myvarsolr:/myvarsolr" "$tag" \
+  bash -c "rm -fr /myvarsolr/*"
+
+ls -l "$myvarsolr/"
+rm -fr "$myvarsolr"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/empty-varsolr-dir-user/test.sh b/solr/docker/tests/cases/empty-varsolr-dir-user/test.sh
new file mode 100755
index 0000000..0f0281f
--- /dev/null
+++ b/solr/docker/tests/cases/empty-varsolr-dir-user/test.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+container_cleanup "$container_name-copier"
+
+myvarsolr="${BUILD_DIR}/myvarsolr-${container_name}"
+prepare_dir_to_mount 8983 "$myvarsolr"
+
+echo "Running $container_name"
+docker run \
+  -v "$myvarsolr:/var/solr" \
+  --name "$container_name" \
+  -u "$(id -u):$(id -g)" \
+  -d "$tag" solr-precreate getting-started
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c getting-started example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/getting-started/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+
+docker exec --user="$(id -u)" "$container_name" ls -lR /var/solr/data
+
+container_cleanup "$container_name"
+
+docker run --rm --user 0:0 -d -e VERBOSE=yes \
+  -v "$myvarsolr:/myvarsolr" "$tag" \
+  bash -c "chown -R $(id -u):$(id -g) /myvarsolr; ls -ld /myvarsolr"
+
+rm -fr "$myvarsolr"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/empty-varsolr-vol-ramdomuser-rootgroup/test.sh b/solr/docker/tests/cases/empty-varsolr-vol-ramdomuser-rootgroup/test.sh
new file mode 100755
index 0000000..826e297
--- /dev/null
+++ b/solr/docker/tests/cases/empty-varsolr-vol-ramdomuser-rootgroup/test.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+container_cleanup "$container_name-copier"
+
+myvarsolr="myvarsolr-${container_name}"
+
+docker volume rm "$myvarsolr" >/dev/null 2>&1 || true
+docker volume create "$myvarsolr"
+
+# when we mount onto /var/solr, that will be owned by "solr"
+
+echo "Running $container_name"
+docker run \
+  --user 777:0 \
+  -v "$myvarsolr:/var/solr" \
+  --name "$container_name" \
+  -d "$tag" solr-precreate getting-started
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c getting-started example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/getting-started/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+
+docker exec --user=7777 "$container_name" ls -l /var/solr/data
+
+container_cleanup "$container_name"
+
+docker volume rm "$myvarsolr"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/empty-varsolr-vol-solr-nocopy/test.sh b/solr/docker/tests/cases/empty-varsolr-vol-solr-nocopy/test.sh
new file mode 100755
index 0000000..eaa39ac
--- /dev/null
+++ b/solr/docker/tests/cases/empty-varsolr-vol-solr-nocopy/test.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+container_cleanup "$container_name-copier"
+
+myvarsolr="myvarsolr-${container_name}"
+
+docker volume rm "$myvarsolr" >/dev/null 2>&1 || true
+docker volume create "$myvarsolr"
+
+# with nocopy, the /var/solr ends up owned by root, so we need to chown it first
+
+docker run \
+  -v "$myvarsolr:/var/solr:nocopy" \
+  --rm \
+  -u "0:0" \
+  "$tag" bash -c "chown 8983:8983 /var/solr"
+
+echo "Running $container_name"
+docker run \
+  -v "$myvarsolr:/var/solr:nocopy" \
+  --name "$container_name" \
+  -d "$tag" solr-precreate getting-started
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c getting-started example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/getting-started/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+
+docker exec --user=solr "$container_name" ls -l /var/solr/data
+
+container_cleanup "$container_name"
+
+docker volume rm "$myvarsolr"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/empty-varsolr-vol-solr/test.sh b/solr/docker/tests/cases/empty-varsolr-vol-solr/test.sh
new file mode 100755
index 0000000..1f1c4c1
--- /dev/null
+++ b/solr/docker/tests/cases/empty-varsolr-vol-solr/test.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+container_cleanup "$container_name-copier"
+
+myvarsolr="myvarsolr-${container_name}"
+
+docker volume rm "$myvarsolr" >/dev/null 2>&1 || true
+docker volume create "$myvarsolr"
+
+# when we mount onto /var/solr, that will be owned by "solr"
+
+echo "Running $container_name"
+docker run \
+  -v "$myvarsolr:/var/solr" \
+  --name "$container_name" \
+  -d "$tag" solr-precreate getting-started
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c getting-started example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/getting-started/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+
+docker exec --user=solr "$container_name" ls -l /var/solr/data
+
+container_cleanup "$container_name"
+
+docker volume rm "$myvarsolr"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/empty-varsolr-vol-user/test.sh b/solr/docker/tests/cases/empty-varsolr-vol-user/test.sh
new file mode 100755
index 0000000..7e6816a
--- /dev/null
+++ b/solr/docker/tests/cases/empty-varsolr-vol-user/test.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+container_cleanup "$container_name-copier"
+
+myvarsolr="myvarsolr-${container_name}"
+
+docker volume rm "$myvarsolr" >/dev/null 2>&1 || true
+docker volume create "$myvarsolr"
+
+# when we mount onto /var/solr, it will be owned by "solr", and it will copy
+# the solr-owned directories and files from the container filesystem onto the
+# the container. So from a container running as solr, modify permissions with
+# setfacl to allow our user to write.
+# If you don't have setfacl then run as root and do: chown -R $(id -u):$(id -g) /var/solr
+docker run \
+  -v "$myvarsolr:/var/solr" \
+  --rm \
+  "$tag" bash -c "setfacl -R -m u:$(id -u):rwx /var/solr"
+
+echo "Running $container_name as $(id -u):$(id -g)"
+docker run \
+  -v "$myvarsolr:/var/solr" \
+  --name "$container_name" \
+  -u "$(id -u):$(id -g)" \
+  -d "$tag" solr-precreate getting-started
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c getting-started example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/getting-started/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+
+container_cleanup "$container_name"
+
+docker volume rm "$myvarsolr"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/gosu/test.sh b/solr/docker/tests/cases/gosu/test.sh
new file mode 100755
index 0000000..ad9444e
--- /dev/null
+++ b/solr/docker/tests/cases/gosu/test.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+#
+# A simple test of gosu. We create a myvarsolr, and chown it
+#
+
+if [[ "$OSTYPE" == "darwin"* ]]; then
+  # TODO: Fix this test on Mac
+  echo "WARNING: Ignoring test 'gosu' on macOS"
+  exit 0
+fi
+
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+myvarsolr="${BUILD_DIR}/myvarsolr-${container_name}"
+prepare_dir_to_mount 8983 "$myvarsolr"
+
+echo "Running $container_name"
+docker run --user 0:0 --name "$container_name" -d -e VERBOSE=yes \
+  -v "$myvarsolr:/var/solr" "$tag" \
+  bash -c "chown -R solr:solr /var/solr; touch /var/solr/root_was_here; exec gosu solr:solr solr-precreate gettingstarted"
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c gettingstarted example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/gettingstarted/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+
+# check test file was created by root
+data=$(docker exec --user=root "$container_name" stat -c %U /var/solr/root_was_here )
+if [[ "$data" == *'No such file or directory' ]]; then
+  echo "Missing /var/solr/root_was_here"
+  exit 1
+fi
+if [[ "$data" != root ]]; then
+  echo "/var/solr/root_was_here is owned by $data"
+  exit 1
+fi
+
+# check core is created by solr
+data=$(docker exec --user=root "$container_name" stat -c %U /var/solr/data/gettingstarted/core.properties )
+if [[ "$data" == *'No such file or directory' ]]; then
+  echo "Missing /var/solr/data/gettingstarted/core.properties"
+  exit 1
+fi
+if [[ "$data" != solr ]]; then
+  echo "/var/solr/data/gettingstarted/core.properties is owned by $data"
+  exit 1
+fi
+
+container_cleanup "$container_name"
+
+# chown it back
+docker run --rm --user 0:0 -d -e VERBOSE=yes \
+  -v "$myvarsolr:/myvarsolr" "$tag" \
+  bash -c "chown -R $(id -u):$(id -g) /myvarsolr; ls -ld /myvarsolr"
+
+rm -fr "$myvarsolr"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/initdb/test.sh b/solr/docker/tests/cases/initdb/test.sh
new file mode 100755
index 0000000..4f60ea4
--- /dev/null
+++ b/solr/docker/tests/cases/initdb/test.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+initdb="$BUILD_DIR/initdb-$container_name"
+prepare_dir_to_mount 8983 "$initdb"
+
+cat > "$initdb/create-was-here.sh" <<EOM
+touch /var/solr/initdb-was-here
+EOM
+cat > "$initdb/ignore-me" <<EOM
+touch /var/solr/should-not-be
+EOM
+
+echo "Running $container_name"
+docker run --name "$container_name" -d -e VERBOSE=yes -v "$initdb:/docker-entrypoint-initdb.d" "$tag"
+
+wait_for_server_started "$container_name"
+
+echo "Checking initdb"
+data=$(docker exec --user=solr "$container_name" ls /var/solr/initdb-was-here)
+if [[ "$data" != /var/solr/initdb-was-here ]]; then
+  echo "Test $TEST_DIR $tag failed; script did not run"
+  exit 1
+fi
+data=$(docker exec --user=solr "$container_name" ls /var/solr/should-not-be; true)
+if [[ -n "$data" ]]; then
+  echo "Test $TEST_DIR $tag failed; should-not-be was"
+  exit 1
+fi
+echo "Checking docker logs"
+log="${BUILD_DIR}/docker.log-$container_name"
+if ! docker logs "$container_name" >"$log" 2>&1; then
+  echo "Could not get logs for $container_name"
+  exit
+fi
+if ! grep -q 'ignoring /docker-entrypoint-initdb.d/ignore-me' "$log"; then
+  echo "missing ignoring message"
+  cat "$log"
+  exit 1
+fi
+rm "$log"
+
+rm -fr "$initdb"
+container_cleanup "$container_name"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/precreate_core/test.sh b/solr/docker/tests/cases/precreate_core/test.sh
new file mode 100755
index 0000000..3113fd7
--- /dev/null
+++ b/solr/docker/tests/cases/precreate_core/test.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+echo "Running $container_name"
+docker run --name "$container_name" -d -e VERBOSE=yes "$tag" solr-precreate gettingstarted
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c gettingstarted example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/gettingstarted/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+container_cleanup "$container_name"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/precreate_core_randomuser_rootgroup/test.sh b/solr/docker/tests/cases/precreate_core_randomuser_rootgroup/test.sh
new file mode 100755
index 0000000..aab55c9
--- /dev/null
+++ b/solr/docker/tests/cases/precreate_core_randomuser_rootgroup/test.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+echo "Running $container_name"
+docker run \
+  --user 7777:0 \
+  --name "$container_name" \
+  -d \
+  -e VERBOSE=yes \
+  "$tag" solr-precreate gettingstarted
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c gettingstarted example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/gettingstarted/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+container_cleanup "$container_name"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/test_log4j/bogus-log4j2.xml b/solr/docker/tests/cases/test_log4j/bogus-log4j2.xml
new file mode 100644
index 0000000..a4931c2
--- /dev/null
+++ b/solr/docker/tests/cases/test_log4j/bogus-log4j2.xml
@@ -0,0 +1 @@
+this is not xml < !
diff --git a/solr/docker/tests/cases/test_log4j/log4j2.xml b/solr/docker/tests/cases/test_log4j/log4j2.xml
new file mode 100644
index 0000000..3f1b691
--- /dev/null
+++ b/solr/docker/tests/cases/test_log4j/log4j2.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<Configuration>
+  <Appenders>
+
+    <Console name="STDOUT" target="SYSTEM_OUT">
+      <PatternLayout>
+        <Pattern>
+          %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%n
+        </Pattern>
+      </PatternLayout>
+    </Console>
+
+    <RollingFile
+        name="RollingFile"
+        fileName="${sys:solr.log.dir}/solr.log"
+        filePattern="${sys:solr.log.dir}/solr.log.%i" >
+      <PatternLayout>
+        <Pattern>
+          %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%n
+        </Pattern>
+      </PatternLayout>
+      <Policies>
+        <OnStartupTriggeringPolicy />
+        <SizeBasedTriggeringPolicy size="32 MB"/>
+      </Policies>
+      <DefaultRolloverStrategy max="10"/>
+    </RollingFile>
+
+    <RollingFile
+        name="SlowFile"
+        fileName="${sys:solr.log.dir}/solr_slow_requests.log"
+        filePattern="${sys:solr.log.dir}/solr_slow_requests.log.%i" >
+      <PatternLayout>
+        <Pattern>
+          %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%n
+        </Pattern>
+      </PatternLayout>
+      <Policies>
+        <OnStartupTriggeringPolicy />
+        <SizeBasedTriggeringPolicy size="32 MB"/>
+      </Policies>
+      <DefaultRolloverStrategy max="10"/>
+    </RollingFile>
+
+  </Appenders>
+  <Loggers>
+    <Logger name="org.apache.hadoop" level="warn"/>
+    <Logger name="org.apache.solr.update.LoggingInfoStream" level="off"/>
+    <Logger name="org.apache.zookeeper" level="warn"/>
+    <Logger name="org.apache.solr.core.SolrCore.SlowRequest" level="info" additivity="false">
+      <AppenderRef ref="SlowFile"/>
+    </Logger>
+
+    <Root level="debug">
+      <AppenderRef ref="RollingFile"/>
+      <AppenderRef ref="STDOUT"/>
+    </Root>
+  </Loggers>
+</Configuration>
diff --git a/solr/docker/tests/cases/test_log4j/test.sh b/solr/docker/tests/cases/test_log4j/test.sh
new file mode 100755
index 0000000..16053fc
--- /dev/null
+++ b/solr/docker/tests/cases/test_log4j/test.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+echo "Running $container_name"
+docker run --name "$container_name" -d -e VERBOSE=yes \
+  -e LOG4J_PROPS=/opt/solr/server/resources/log4j2.xml \
+  -v "$TEST_DIR/log4j2.xml:/opt/solr/server/resources/log4j2.xml" \
+  -v "$TEST_DIR/bogus-log4j2.xml:/var/solr/log4j2.xml" \
+  "$tag" solr-precreate gettingstarted
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c gettingstarted example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/gettingstarted/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+data=$(docker exec --user=solr "$container_name" grep 'DEBUG (main)' /var/solr/logs/solr.log | wc -l)
+if (( data == 0 )); then
+  echo "missing DEBUG lines in the log"
+  exit 1
+fi
+
+container_cleanup "$container_name"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/user_volume/test.sh b/solr/docker/tests/cases/user_volume/test.sh
new file mode 100755
index 0000000..8edb483
--- /dev/null
+++ b/solr/docker/tests/cases/user_volume/test.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+container_cleanup "$container_name-copier"
+
+myvarsolr="${BUILD_DIR}/myvarsolr-${container_name}"
+prepare_dir_to_mount 8983 "$myvarsolr"
+mylogs="${BUILD_DIR}/mylogs-${container_name}"
+prepare_dir_to_mount 8983 "$mylogs"
+myconf="${BUILD_DIR}/myconf-${container_name}"
+configsets="${BUILD_DIR}/configsets-${container_name}"
+
+# create a core by hand:
+rm -fr "$myconf" "$configsets" 2>/dev/null
+docker create --name "$container_name-copier" "$tag"
+docker cp "$container_name-copier:/opt/solr/server/solr/configsets" "$configsets"
+docker rm "$container_name-copier"
+for d in data_driven_schema_configs _default; do
+  if [ -d "$configsets/$d" ]; then
+    cp -r "$configsets/$d/conf" "$myconf"
+    break
+  fi
+done
+rm -fr "$configsets"
+if [ ! -d "$myconf" ]; then
+  echo "Could not get config"
+  exit 1
+fi
+if [ ! -f "$myconf/solrconfig.xml" ]; then
+  find "$myconf"
+  echo "ERROR: no solrconfig.xml"
+  exit 1
+fi
+
+# create a directory for the core
+mkdir -p "$myvarsolr/data/mycore"
+mkdir -p "$myvarsolr/logs"
+touch "$myvarsolr/data/mycore/core.properties"
+
+echo "Running $container_name"
+docker run \
+  -v "$myvarsolr:/var/solr" \
+  -v "$myconf:/var/solr/data/mycore/conf:ro" \
+  -v "$mylogs:/var/solr/logs" \
+  --user "$(id -u):$(id -g)" \
+  --name "$container_name" \
+  -d "$tag"
+
+wait_for_container_and_solr "$container_name"
+
+echo "Loading data"
+docker exec --user=solr "$container_name" bin/post -c mycore example/exampledocs/manufacturers.xml
+sleep 1
+echo "Checking data"
+data=$(docker exec --user=solr "$container_name" wget -q -O - 'http://localhost:8983/solr/mycore/select?q=id%3Adell')
+if ! grep -E -q 'One Dell Way Round Rock, Texas 78682' <<<"$data"; then
+  echo "Test $TEST_NAME $tag failed; data did not load"
+  exit 1
+fi
+container_cleanup "$container_name"
+
+rm -fr "$myconf" "$myvarsolr" "$mylogs" "$configsets"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/cases/version/test.sh b/solr/docker/tests/cases/version/test.sh
new file mode 100755
index 0000000..0f8c7ee
--- /dev/null
+++ b/solr/docker/tests/cases/version/test.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+#
+set -euo pipefail
+
+TEST_DIR="${TEST_DIR:-$(dirname -- "${BASH_SOURCE[0]}")}"
+source "${TEST_DIR}/../../shared.sh"
+
+echo "Running $container_name"
+docker run --name "$container_name" -d "$tag"
+
+wait_for_server_started "$container_name"
+
+echo "Checking that the OS matches the tag '$tag'"
+if echo "$tag" | grep -q -- -alpine; then
+  alpine_version=$(docker exec --user=solr "$container_name" cat /etc/alpine-release || true)
+  if [[ -z $alpine_version ]]; then
+    echo "Could not get alpine version from container $container_name"
+    container_cleanup "$container_name"
+    exit 1
+  fi
+  echo "Alpine $alpine_version"
+else
+  debian_version=$(docker exec --user=solr "$container_name" cat /etc/debian_version || true)
+  if [[ -z $debian_version ]]; then
+    echo "Could not get debian version from container $container_name"
+    container_cleanup "$container_name"
+    exit 1
+  fi
+  echo "Debian $debian_version"
+fi
+
+# check that the version of Solr matches the tag
+changelog_version=$(docker exec --user=solr "$container_name" bash -c "grep -E '^==========* ' /opt/solr/CHANGES.txt | head -n 1 | tr -d '= '")
+echo "Solr version $changelog_version"
+solr_version_from_tag=$(echo "$tag" | sed -e 's/^.*://' -e 's/-.*//')
+
+if [[ $changelog_version != "$solr_version_from_tag" ]]; then
+  echo "Solr version mismatch"
+  container_cleanup "$container_name"
+  exit 1
+fi
+
+container_cleanup "$container_name"
+
+echo "Test $TEST_NAME $tag succeeded"
diff --git a/solr/docker/tests/shared.sh b/solr/docker/tests/shared.sh
new file mode 100755
index 0000000..0537db7
--- /dev/null
+++ b/solr/docker/tests/shared.sh
@@ -0,0 +1,133 @@
+#!/bin/bash
+#
+# Shared functions for testing
+
+function container_cleanup {
+  local container_name
+  container_name=$1
+  previous=$(docker inspect "$container_name" --format '{{.ID}}' 2>/dev/null || true)
+  if [[ -n $previous ]]; then
+    container_status=$(docker inspect --format='{{.State.Status}}' "$previous" 2>/dev/null)
+    if [[ $container_status == 'running' ]]; then
+      echo "killing $previous"
+      docker kill "$previous" 2>/dev/null || true
+      sleep 2
+    fi
+    echo "removing $previous"
+    docker rm "$previous" 2>/dev/null || true
+  fi
+}
+
+function wait_for_container_and_solr {
+  local container_name
+  container_name=$1
+  wait_for_server_started "$container_name" 0
+
+  printf '\nWaiting for Solr...\n'
+  local status
+  status=$(docker exec "$container_name" /opt/docker-solr/scripts/wait-for-solr.sh --max-attempts 60 --wait-seconds 1)
+#  echo "Got status from Solr: $status"
+  if ! grep -E -i -q 'Solr is running' <<<"$status"; then
+    echo "Solr did not start"
+    container_cleanup "$container_name"
+    exit 1
+  else
+    echo "Solr is running"
+  fi
+  sleep 4
+}
+
+function wait_for_server_started {
+  local container_name
+  container_name=$1
+  local sleep_time
+  sleep_time=5
+  if [ -n "${2:-}" ]; then
+    sleep_time=$2
+  fi
+  echo "Waiting for container start: $container_name"
+  local TIMEOUT_SECONDS
+  TIMEOUT_SECONDS=$(( 5 * 60 ))
+  local started
+  started=$(date +%s)
+  local log
+  log="${BUILD_DIR}/${container_name}.log"
+  while true; do
+    docker logs "$container_name" > "${log}" 2>&1
+    if grep -E -q '(o\.e\.j\.s\.Server Started|Started SocketConnector)' "${log}" ; then
+      break
+    fi
+
+    local container_status
+    container_status=$(docker inspect --format='{{.State.Status}}' "$container_name")
+    if [[ $container_status == 'exited' ]]; then
+      echo "container exited"
+      exit 1
+    fi
+
+    if (( $(date +%s) > started + TIMEOUT_SECONDS )); then
+      echo "giving up after $TIMEOUT_SECONDS seconds"
+      exit 1
+    fi
+    printf '.'
+    sleep 2
+  done
+  echo "Server started"
+  rm "${log}"
+  sleep "$sleep_time"
+}
+
+function prepare_dir_to_mount {
+  local userid
+  userid=8983
+  local folder
+  folder="${BUILD_DIR}/myvarsolr"
+  if [ -n "$1" ]; then
+    userid=$1
+  fi
+  if [ -n "$2" ]; then
+    folder=$2
+  fi
+  rm -fr "$folder" >/dev/null 2>&1
+  mkdir "$folder"
+  #echo "***** Created varsolr folder $BUILD_DIR / $folder"
+
+  # The /var/solr mountpoint is owned by solr, so when we bind mount there our directory,
+  # owned by the current user in the host, will show as owned by solr, and our attempts
+  # to write to it as the user will fail. To deal with that, set the ACL to allow that.
+  # If you can't use setfacl (eg on macOS), you'll have to chown the directory to 8983, or apply world
+  # write permissions.
+  if command -v setfacl &> /dev/null; then
+    setfacl -m "u:$userid:rwx" "$folder"
+  fi
+}
+
+
+# Shared setup
+
+if (( $# == 0 )); then
+  echo "Usage: ${TEST_DIR}/test.sh <tag>"
+  exit
+fi
+tag=$1
+
+if [[ -n "${DEBUG:-}" ]]; then
+  set -x
+fi
+
+TEST_NAME="$(basename -- "${TEST_DIR}")"
+
+# Create build directory if it hasn't been provided already
+if [[ -z ${BUILD_DIR:-} ]]; then
+  BASE_DIR="$(dirname -- "${BASH_SOURCE-$0}")"
+  BASE_DIR="$(cd "${BASE_DIR}/.." && pwd)"
+  BUILD_DIR="${BASE_DIR}/build/tmp/tests/${TEST_NAME}"
+fi
+mkdir -p "${BUILD_DIR}"
+
+echo "Test $TEST_DIR $tag"
+echo "Test logs and build files can be found at: ${BUILD_DIR}"
+container_name="test-$(echo "${TEST_NAME}" | tr ':/-' '_')-$(echo "${tag}" | tr ':/-' '_')"
+
+echo "Cleaning up left-over containers from previous runs"
+container_cleanup "${container_name}"
\ No newline at end of file


[lucene-solr] 23/39: LUCENE-9475: Switch validateSourcePatterns away from Ant legacy (#1806)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 92fb5e2fdfaa26c89345a38ba32abd6ee429f391
Author: Uwe Schindler <us...@apache.org>
AuthorDate: Mon Aug 31 12:52:04 2020 +0200

    LUCENE-9475: Switch validateSourcePatterns away from Ant legacy (#1806)
---
 gradle/validation/validate-source-patterns.gradle  | 333 ++++++++++++++++++---
 .../check-source-patterns.groovy                   | 217 --------------
 2 files changed, 294 insertions(+), 256 deletions(-)

diff --git a/gradle/validation/validate-source-patterns.gradle b/gradle/validation/validate-source-patterns.gradle
index b121f42..7363308 100644
--- a/gradle/validation/validate-source-patterns.gradle
+++ b/gradle/validation/validate-source-patterns.gradle
@@ -15,58 +15,313 @@
  * limitations under the License.
  */
 
-// This should be eventually rewritten in plain gradle. For now, delegate to
-// the ant/groovy script we already have.
+import org.apache.rat.Defaults
+import org.apache.rat.document.impl.FileDocument
+import org.apache.rat.api.MetaData
+
+import javax.inject.Inject;
+import org.gradle.internal.logging.progress.ProgressLoggerFactory
+import org.gradle.internal.logging.progress.ProgressLogger
+
+buildscript {
+  repositories {
+    mavenCentral()
+  }
+
+  dependencies {
+    classpath "org.apache.rat:apache-rat:${scriptDepVersions['apache-rat']}"
+  }
+}
+
+def extensions = [
+    'adoc',
+    'bat',
+    'cmd',
+    'css',
+    'g4',
+    'gradle',
+    'groovy',
+    'html',
+    'java',
+    'jflex',
+    'jj',
+    'js',
+    'json',
+    'md',
+    'mdtext',
+    'pl',
+    'policy',
+    'properties',
+    'py',
+    'sh',
+    'template',
+    'vm',
+    'xml',
+    'xsl',
+]
+
+// Create source validation task local for each project's files.
+subprojects {
+  task validateSourcePatterns(type: ValidateSourcePatternsTask) { task ->
+    group = 'Verification'
+    description = 'Validate Source Patterns'
+
+    // This task has no proper outputs.
+    setupDummyOutputs(task)
+
+    sourceFiles = fileTree(projectDir) {
+      extensions.each{
+        include "**/*.${it}"
+      }
+      
+      // Don't go into child projects (scanned separately).
+      childProjects.keySet().each{
+        exclude "${it}/**"
+      }
+
+      // default excludes.
+      exclude 'build/**'
+    }
+  }
+
+  // Add source validation to per-project checks as well.
+  check.dependsOn validateSourcePatterns
+}
+
+configure(project(':lucene:benchmark')) {
+  project.tasks.withType(ValidateSourcePatternsTask) {
+    sourceFiles.exclude 'temp/**'
+    sourceFiles.exclude 'work/**'
+  }
+}
+
+configure(project(':solr:core')) {
+  project.tasks.withType(ValidateSourcePatternsTask) {
+    sourceFiles.exclude 'src/**/CheckLoggingConfiguration.java'
+    sourceFiles.exclude 'src/test/org/apache/hadoop/**'
+  }
+}
 
 configure(rootProject) {
-  task("validateSourcePatterns", type: ValidateSourcePatternsTask) {
+  task validateSourcePatterns(type: ValidateSourcePatternsTask) { task ->
     group = 'Verification'
     description = 'Validate Source Patterns'
-    
-    sourceFiles = project.fileTree(project.rootDir) {
-      [
-        'java', 'jflex', 'py', 'pl', 'g4', 'jj', 'html', 'js',
-        'css', 'xml', 'xsl', 'vm', 'sh', 'cmd', 'bat', 'policy',
-        'properties', 'mdtext', 'groovy', 'gradle',
-        'template', 'adoc', 'json',
-      ].each{
-        include "lucene/**/*.${it}"
-        include "solr/**/*.${it}"
-        include "dev-tools/**/*.${it}"
-        include "gradle/**/*.${it}"
-        include "*.${it}"
+
+    // This task has no proper outputs.
+    setupDummyOutputs(task)
+
+    sourceFiles = fileTree(projectDir) {
+      extensions.each{
+        include "**/*.${it}"
+      }
+
+      // We do not scan for *.txt by default (broken files in subprojects),
+      // but in root we can do this).
+      include '**/*.txt'
+
+      // Don't go into child projects (scanned separately).
+      childProjects.keySet().each{
+        exclude "${it}/**"
       }
-      // TODO: For now we don't scan txt / md files, so we
-      // check licenses in top-level folders separately:
-      include '*.txt'
-      include '*/*.txt'
-      include '*.md'
-      include '*/*.md'
-      // excludes:
+
+      // default excludes.
       exclude '**/build/**'
-      exclude '**/dist/**'
       exclude 'dev-tools/missing-doclet/src/**/*.java' // <-- TODO: remove once we allow "var" on master
-      exclude 'lucene/benchmark/work/**'
-      exclude 'lucene/benchmark/temp/**'
-      exclude '**/CheckLoggingConfiguration.java'
-      exclude 'solr/core/src/test/org/apache/hadoop/**'
-      exclude '**/validate-source-patterns.gradle' // ourselves :-)
+
+      // ourselves :-)
+      exclude 'gradle/validation/validate-source-patterns.gradle'
     }
   }
 
-  dependencies {
-    checkSourceDeps "org.codehaus.groovy:groovy-all:2.4.17"
-    checkSourceDeps "org.apache.rat:apache-rat:${scriptDepVersions['apache-rat']}"
+  check.dependsOn validateSourcePatterns
+}
+
+class ValidateSourcePatternsTask extends DefaultTask {
+  private ProgressLoggerFactory progressLoggerFactory
+
+  @InputFiles
+  FileTree sourceFiles
+
+  @Inject
+  ValidateSourcePatternsTask(ProgressLoggerFactory progressLoggerFactory) {
+    this.progressLoggerFactory = progressLoggerFactory
   }
+  
+  @TaskAction
+  public void check() {
+    def invalidPatterns = [
+      (~$/@author\b/$) : '@author javadoc tag',
+      (~$/(?i)\bno(n|)commit\b/$) : 'nocommit',
+      (~$/\bTOOD:/$) : 'TOOD instead TODO',
+      (~$/\t/$) : 'tabs instead spaces',
+      (~$/\Q/**\E((?:\s)|(?:\*))*\Q{@inheritDoc}\E((?:\s)|(?:\*))*\Q*/\E/$) : '{@inheritDoc} on its own is unnecessary',
+      (~$/\$$(?:LastChanged)?Date\b/$) : 'svn keyword',
+      (~$/\$$(?:(?:LastChanged)?Revision|Rev)\b/$) : 'svn keyword',
+      (~$/\$$(?:LastChangedBy|Author)\b/$) : 'svn keyword',
+      (~$/\$$(?:Head)?URL\b/$) : 'svn keyword',
+      (~$/\$$Id\b/$) : 'svn keyword',
+      (~$/\$$Header\b/$) : 'svn keyword',
+      (~$/\$$Source\b/$) : 'svn keyword',
+      (~$/^\uFEFF/$) : 'UTF-8 byte order mark',
+      (~$/import java\.lang\.\w+;/$) : 'java.lang import is unnecessary'
+    ]
+
+    // Python and others merrily use var declarations, this is a problem _only_ in Java at least for 8x where we're forbidding var declarations
+    def invalidJavaOnlyPatterns = [
+      (~$/\n\s*var\s+.*=.*<>.*/$) : 'Diamond operators should not be used with var',
+      (~$/\n\s*var\s+/$) : 'var is not allowed in until we stop development on the 8x code line'
+    ]
+
+    def found = 0;
+    def violations = new TreeSet();
+    def reportViolation = { f, name ->
+      logger.error('{}: {}', name, f);
+      violations.add(name);
+      found++;
+    }
+
+    def javadocsPattern = ~$/(?sm)^\Q/**\E(.*?)\Q*/\E/$;
+    def javaCommentPattern = ~$/(?sm)^\Q/*\E(.*?)\Q*/\E/$;
+    def xmlCommentPattern = ~$/(?sm)\Q<!--\E(.*?)\Q-->\E/$;
+    def lineSplitter = ~$/[\r\n]+/$;
+    def singleLineSplitter = ~$/\r?\n/$;
+    def licenseMatcher = Defaults.createDefaultMatcher();
+    def validLoggerPattern = ~$/(?s)\b(private\s|static\s|final\s){3}+\s*Logger\s+\p{javaJavaIdentifierStart}+\s+=\s+\QLoggerFactory.getLogger(MethodHandles.lookup().lookupClass());\E/$;
+    def validLoggerNamePattern = ~$/(?s)\b(private\s|static\s|final\s){3}+\s*Logger\s+log+\s+=\s+\QLoggerFactory.getLogger(MethodHandles.lookup().lookupClass());\E/$;
+    def packagePattern = ~$/(?m)^\s*package\s+org\.apache.*;/$;
+    def xmlTagPattern = ~$/(?m)\s*<[a-zA-Z].*/$;
+    def sourceHeaderPattern = ~$/\[source\b.*/$;
+    def blockBoundaryPattern = ~$/----\s*/$;
+    def blockTitlePattern = ~$/\..*/$;
+    def unescapedSymbolPattern = ~$/(?<=[^\\]|^)([-=]>|<[-=])/$; // SOLR-10883
+    def extendsLuceneTestCasePattern = ~$/public.*?class.*?extends.*?LuceneTestCase[^\n]*?\n/$;
+    def validSPINameJavadocTag = ~$/(?s)\s*\*\s*@lucene\.spi\s+\{@value #NAME\}/$;
+
+    def isLicense = { matcher, ratDocument ->
+      licenseMatcher.reset();
+      return lineSplitter.split(matcher.group(1)).any{ licenseMatcher.match(ratDocument, it) };
+    }
+
+    def checkLicenseHeaderPrecedes = { f, description, contentPattern, commentPattern, text, ratDocument ->
+      def contentMatcher = contentPattern.matcher(text);
+      if (contentMatcher.find()) {
+        def contentStartPos = contentMatcher.start();
+        def commentMatcher = commentPattern.matcher(text);
+        while (commentMatcher.find()) {
+          if (isLicense(commentMatcher, ratDocument)) {
+            if (commentMatcher.start() < contentStartPos) {
+              break; // This file is all good, so break loop: license header precedes 'description' definition
+            } else {
+              reportViolation(f, description+' declaration precedes license header');
+            }
+          }
+        }
+      }
+    }
 
-  task validateSourcePatterns() {
-    doFirst {
-      ant.taskdef(
-          name: "groovy",
-          classname: "org.codehaus.groovy.ant.Groovy",
-          classpath: configurations.checkSourceDeps.asPath)
+    def checkMockitoAssume = { f, text ->
+      if (text.contains("mockito") && !text.contains("assumeWorkingMockito()")) {
+        reportViolation(f, 'File uses Mockito but has no assumeWorkingMockito() call');
+      }
+    }
+
+    def checkForUnescapedSymbolSubstitutions = { f, text ->
+      def inCodeBlock = false;
+      def underSourceHeader = false;
+      def lineNumber = 0;
+      singleLineSplitter.split(text).each {
+        ++lineNumber;
+        if (underSourceHeader) { // This line is either a single source line, or the boundary of a code block
+          inCodeBlock = blockBoundaryPattern.matcher(it).matches();
+          if ( ! blockTitlePattern.matcher(it).matches()) {
+            underSourceHeader = false;
+          }
+        } else {
+          if (inCodeBlock) {
+            inCodeBlock = ! blockBoundaryPattern.matcher(it).matches();
+          } else {
+            underSourceHeader = sourceHeaderPattern.matcher(it).lookingAt();
+            if ( ! underSourceHeader) {
+              def unescapedSymbolMatcher = unescapedSymbolPattern.matcher(it);
+              if (unescapedSymbolMatcher.find()) {
+                reportViolation(f, 'Unescaped symbol "' + unescapedSymbolMatcher.group(1) + '" on line #' + lineNumber);
+              }
+            }
+          }
+        }
+      }
+    }
+
+    ProgressLogger progress = progressLoggerFactory.newOperation(this.class)
+    progress.start(this.name, this.name)
+
+    sourceFiles.each{ f ->
+      progress.progress("Scanning ${f.name}")
+      logger.debug('Scanning source file: {}', f);
+
+      def text = f.getText('UTF-8');
+      invalidPatterns.each{ pattern,name ->
+        if (pattern.matcher(text).find()) {
+          reportViolation(f, name);
+        }
+      }
+      def javadocsMatcher = javadocsPattern.matcher(text);
+      def ratDocument = new FileDocument(f);
+      while (javadocsMatcher.find()) {
+        if (isLicense(javadocsMatcher, ratDocument)) {
+          reportViolation(f, String.format(Locale.ENGLISH, 'javadoc-style license header [%s]',
+            ratDocument.getMetaData().value(MetaData.RAT_URL_LICENSE_FAMILY_NAME)));
+        }
+      }
+      if (f.name.endsWith('.java')) {
+        if (text.contains('org.slf4j.LoggerFactory')) {
+          if (!validLoggerPattern.matcher(text).find()) {
+            reportViolation(f, 'invalid logging pattern [not private static final, uses static class name]');
+          }
+          if (!validLoggerNamePattern.matcher(text).find()) {
+            reportViolation(f, 'invalid logger name [log, uses static class name, not specialized logger]')
+          }
+        }
+        // make sure that SPI names of all tokenizers/charfilters/tokenfilters are documented
+        if (!f.name.contains("Test") && !f.name.contains("Mock") && !text.contains("abstract class") &&
+            !f.name.equals("TokenizerFactory.java") && !f.name.equals("CharFilterFactory.java") && !f.name.equals("TokenFilterFactory.java") &&
+            (f.name.contains("TokenizerFactory") && text.contains("extends TokenizerFactory") ||
+                f.name.contains("CharFilterFactory") && text.contains("extends CharFilterFactory") ||
+                f.name.contains("FilterFactory") && text.contains("extends TokenFilterFactory"))) {
+          if (!validSPINameJavadocTag.matcher(text).find()) {
+            reportViolation(f, 'invalid spi name documentation')
+          }
+        }
+        checkLicenseHeaderPrecedes(f, 'package', packagePattern, javaCommentPattern, text, ratDocument);
+        if (f.name.contains("Test")) {
+          checkMockitoAssume(f, text);
+        }
+
+        if (project.path.startsWith(':solr:')
+            && f.name.equals("SolrTestCase.java") == false
+            && f.name.equals("TestXmlQParser.java") == false) {
+          if (extendsLuceneTestCasePattern.matcher(text).find()) {
+            reportViolation(f, "Solr test cases should extend SolrTestCase rather than LuceneTestCase");
+          }
+        }
+        invalidJavaOnlyPatterns.each { pattern,name ->
+          if (pattern.matcher(text).find()) {
+            reportViolation(f, name);
+          }
+        }
+      }
+      if (f.name.endsWith('.xml')) {
+        checkLicenseHeaderPrecedes(f, '<tag>', xmlTagPattern, xmlCommentPattern, text, ratDocument);
+      }
+      if (f.name.endsWith('.adoc')) {
+        checkForUnescapedSymbolSubstitutions(f, text);
+      }
+    }
+    progress.completed()
 
-      ant.groovy(src: rootProject.file("gradle/validation/validate-source-patterns/check-source-patterns.groovy"))
+    if (found) {
+      throw new GradleException(String.format(Locale.ENGLISH, 'Found %d violations in source files (%s).',
+        found, violations.join(', ')));
     }
   }
 }
diff --git a/gradle/validation/validate-source-patterns/check-source-patterns.groovy b/gradle/validation/validate-source-patterns/check-source-patterns.groovy
deleted file mode 100644
index aabcd27..0000000
--- a/gradle/validation/validate-source-patterns/check-source-patterns.groovy
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/** Task script that is called by Ant's build.xml file:
- * Checks that there are no @author javadoc tags, tabs, 
- * svn keywords, javadoc-style licenses, or nocommits.
- */
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.rat.Defaults;
-import org.apache.rat.document.impl.FileDocument;
-import org.apache.rat.api.MetaData;
-
-def extensions = [
-  'java', 'jflex', 'py', 'pl', 'g4', 'jj', 'html', 'js',
-  'css', 'xml', 'xsl', 'vm', 'sh', 'cmd', 'bat', 'policy',
-  'properties', 'mdtext', 'groovy',
-  'template', 'adoc', 'json',
-];
-def invalidPatterns = [
-  (~$/@author\b/$) : '@author javadoc tag',
-  (~$/(?i)\bno(n|)commit\b/$) : 'nocommit',
-  (~$/\bTOOD:/$) : 'TOOD instead TODO',
-  (~$/\t/$) : 'tabs instead spaces',
-  (~$/\Q/**\E((?:\s)|(?:\*))*\Q{@inheritDoc}\E((?:\s)|(?:\*))*\Q*/\E/$) : '{@inheritDoc} on its own is unnecessary',
-  (~$/\$$(?:LastChanged)?Date\b/$) : 'svn keyword',
-  (~$/\$$(?:(?:LastChanged)?Revision|Rev)\b/$) : 'svn keyword',
-  (~$/\$$(?:LastChangedBy|Author)\b/$) : 'svn keyword',
-  (~$/\$$(?:Head)?URL\b/$) : 'svn keyword',
-  (~$/\$$Id\b/$) : 'svn keyword',
-  (~$/\$$Header\b/$) : 'svn keyword',
-  (~$/\$$Source\b/$) : 'svn keyword',
-  (~$/^\uFEFF/$) : 'UTF-8 byte order mark',
-  (~$/import java\.lang\.\w+;/$) : 'java.lang import is unnecessary'
-]
-
-def baseDir = properties['basedir'];
-def baseDirLen = baseDir.length() + 1;
-
-def found = 0;
-def violations = new TreeSet();
-def reportViolation = { f, name ->
-  task.log(name + ': ' + f.toString().substring(baseDirLen).replace(File.separatorChar, (char)'/'), Project.MSG_ERR);
-  violations.add(name);
-  found++;
-}
-
-def javadocsPattern = ~$/(?sm)^\Q/**\E(.*?)\Q*/\E/$;
-def javaCommentPattern = ~$/(?sm)^\Q/*\E(.*?)\Q*/\E/$;
-def xmlCommentPattern = ~$/(?sm)\Q<!--\E(.*?)\Q-->\E/$;
-def lineSplitter = ~$/[\r\n]+/$;
-def singleLineSplitter = ~$/\r?\n/$;
-def licenseMatcher = Defaults.createDefaultMatcher();
-def validLoggerPattern = ~$/(?s)\b(private\s|static\s|final\s){3}+\s*Logger\s+\p{javaJavaIdentifierStart}+\s+=\s+\QLoggerFactory.getLogger(MethodHandles.lookup().lookupClass());\E/$;
-def validLoggerNamePattern = ~$/(?s)\b(private\s|static\s|final\s){3}+\s*Logger\s+log+\s+=\s+\QLoggerFactory.getLogger(MethodHandles.lookup().lookupClass());\E/$;
-def packagePattern = ~$/(?m)^\s*package\s+org\.apache.*;/$;
-def xmlTagPattern = ~$/(?m)\s*<[a-zA-Z].*/$;
-def sourceHeaderPattern = ~$/\[source\b.*/$;
-def blockBoundaryPattern = ~$/----\s*/$;
-def blockTitlePattern = ~$/\..*/$;
-def unescapedSymbolPattern = ~$/(?<=[^\\]|^)([-=]>|<[-=])/$; // SOLR-10883
-def extendsLuceneTestCasePattern = ~$/public.*?class.*?extends.*?LuceneTestCase[^\n]*?\n/$;
-def validSPINameJavadocTag = ~$/(?s)\s*\*\s*@lucene\.spi\s+\{@value #NAME\}/$;
-
-def isLicense = { matcher, ratDocument ->
-  licenseMatcher.reset();
-  return lineSplitter.split(matcher.group(1)).any{ licenseMatcher.match(ratDocument, it) };
-}
-
-def checkLicenseHeaderPrecedes = { f, description, contentPattern, commentPattern, text, ratDocument ->
-  def contentMatcher = contentPattern.matcher(text);
-  if (contentMatcher.find()) {
-    def contentStartPos = contentMatcher.start();
-    def commentMatcher = commentPattern.matcher(text);
-    while (commentMatcher.find()) {
-      if (isLicense(commentMatcher, ratDocument)) {
-        if (commentMatcher.start() < contentStartPos) {
-          break; // This file is all good, so break loop: license header precedes 'description' definition
-        } else {
-          reportViolation(f, description+' declaration precedes license header');
-        }
-      }
-    }
-  }
-}
-
-def checkMockitoAssume = { f, text ->
-  if (text.contains("mockito") && !text.contains("assumeWorkingMockito()")) {
-    reportViolation(f, 'File uses Mockito but has no assumeWorkingMockito() call');
-  }
-}
-
-def checkForUnescapedSymbolSubstitutions = { f, text ->
-  def inCodeBlock = false;
-  def underSourceHeader = false;
-  def lineNumber = 0;
-  singleLineSplitter.split(text).each {
-    ++lineNumber;
-    if (underSourceHeader) { // This line is either a single source line, or the boundary of a code block
-      inCodeBlock = blockBoundaryPattern.matcher(it).matches();
-      if ( ! blockTitlePattern.matcher(it).matches()) {
-        underSourceHeader = false;
-      }
-    } else {
-      if (inCodeBlock) {
-        inCodeBlock = ! blockBoundaryPattern.matcher(it).matches();
-      } else {
-        underSourceHeader = sourceHeaderPattern.matcher(it).lookingAt();
-        if ( ! underSourceHeader) {
-          def unescapedSymbolMatcher = unescapedSymbolPattern.matcher(it);
-          if (unescapedSymbolMatcher.find()) {
-            reportViolation(f, 'Unescaped symbol "' + unescapedSymbolMatcher.group(1) + '" on line #' + lineNumber);
-          }
-        }
-      }
-    }
-  }
-}
-
-ant.fileScanner{
-  fileset(dir: baseDir){
-    extensions.each{
-      include(name: 'lucene/**/*.' + it)
-      include(name: 'solr/**/*.' + it)
-      include(name: 'dev-tools/**/*.' + it)
-      include(name: '*.' + it)
-    }
-    // TODO: For now we don't scan txt / md files, so we
-    // check licenses in top-level folders separately:
-    include(name: '*.txt')
-    include(name: '*/*.txt')
-    include(name: '*.md')
-    include(name: '*/*.md')
-    // excludes:
-    exclude(name: '**/build/**')
-    exclude(name: '**/dist/**')
-    exclude(name: 'lucene/benchmark/work/**')
-    exclude(name: 'lucene/benchmark/temp/**')
-    exclude(name: '**/CheckLoggingConfiguration.java')
-    exclude(name: 'lucene/tools/src/groovy/check-source-patterns.groovy') // ourselves :-)
-    exclude(name: 'solr/core/src/test/org/apache/hadoop/**')
-  }
-}.each{ f ->
-  task.log('Scanning file: ' + f, Project.MSG_VERBOSE);
-  def text = f.getText('UTF-8');
-  invalidPatterns.each{ pattern,name ->
-    if (pattern.matcher(text).find()) {
-      reportViolation(f, name);
-    }
-  }
-  def javadocsMatcher = javadocsPattern.matcher(text);
-  def ratDocument = new FileDocument(f);
-  while (javadocsMatcher.find()) {
-    if (isLicense(javadocsMatcher, ratDocument)) {
-      reportViolation(f, String.format(Locale.ENGLISH, 'javadoc-style license header [%s]',
-        ratDocument.getMetaData().value(MetaData.RAT_URL_LICENSE_FAMILY_NAME)));
-    }
-  }
-  if (f.name.endsWith('.java')) {
-    if (text.contains('org.slf4j.LoggerFactory')) {
-      if (!validLoggerPattern.matcher(text).find()) {
-        reportViolation(f, 'invalid logging pattern [not private static final, uses static class name]');
-      }
-      if (!validLoggerNamePattern.matcher(text).find()) {
-        reportViolation(f, 'invalid logger name [log, uses static class name, not specialized logger]')
-      }
-    }
-    // make sure that SPI names of all tokenizers/charfilters/tokenfilters are documented
-    if (!f.name.contains("Test") && !f.name.contains("Mock") && !text.contains("abstract class") &&
-        !f.name.equals("TokenizerFactory.java") && !f.name.equals("CharFilterFactory.java") && !f.name.equals("TokenFilterFactory.java") &&
-        (f.name.contains("TokenizerFactory") && text.contains("extends TokenizerFactory") ||
-            f.name.contains("CharFilterFactory") && text.contains("extends CharFilterFactory") ||
-            f.name.contains("FilterFactory") && text.contains("extends TokenFilterFactory"))) {
-      if (!validSPINameJavadocTag.matcher(text).find()) {
-        reportViolation(f, 'invalid spi name documentation')
-      }
-    }
-    checkLicenseHeaderPrecedes(f, 'package', packagePattern, javaCommentPattern, text, ratDocument);
-    if (f.name.contains("Test")) {
-      checkMockitoAssume(f, text);
-    }
-
-    if (f.path.substring(baseDirLen).contains("solr/")
-        && f.name.equals("SolrTestCase.java") == false
-        && f.name.equals("TestXmlQParser.java") == false) {
-      if (extendsLuceneTestCasePattern.matcher(text).find()) {
-        reportViolation(f, "Solr test cases should extend SolrTestCase rather than LuceneTestCase");
-      }
-    }
-  }
-  if (f.name.endsWith('.xml') || f.name.endsWith('.xml.template')) {
-    checkLicenseHeaderPrecedes(f, '<tag>', xmlTagPattern, xmlCommentPattern, text, ratDocument);
-  }
-  if (f.name.endsWith('.adoc')) {
-    checkForUnescapedSymbolSubstitutions(f, text);
-  }
-};
-
-if (found) {
-  throw new BuildException(String.format(Locale.ENGLISH, 'Found %d violations in source files (%s).',
-    found, violations.join(', ')));
-}


[lucene-solr] 15/39: LUCENE-9518: Add sanity to gradle archiving tasks (predictable order, default permissions, fail on duplicates) (#1851)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 4c9931aa2652f292515908028bc03921e34e597c
Author: Dawid Weiss <da...@carrotsearch.com>
AuthorDate: Thu Sep 10 09:48:04 2020 +0200

    LUCENE-9518: Add sanity to gradle archiving tasks (predictable order, default permissions, fail on duplicates) (#1851)
---
 build.gradle                        |  1 +
 gradle/hacks/gradle-archives.gradle | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/build.gradle b/build.gradle
index f01045b..45cb6a6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -173,6 +173,7 @@ apply from: file('gradle/documentation/changes-to-html.gradle')
 apply from: file('gradle/documentation/markdown.gradle')
 apply from: file('gradle/documentation/render-javadoc.gradle')
 
+apply from: file('gradle/hacks/gradle-archives.gradle')
 apply from: file('gradle/hacks/findbugs.gradle')
 apply from: file('gradle/hacks/gradle.gradle')
 apply from: file('gradle/hacks/hashmapAssertions.gradle')
diff --git a/gradle/hacks/gradle-archives.gradle b/gradle/hacks/gradle-archives.gradle
new file mode 100644
index 0000000..a10a640
--- /dev/null
+++ b/gradle/hacks/gradle-archives.gradle
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */ 
+
+// LUCENE-9518: Set up sane defaults for any gradle archiving task.
+allprojects {
+  tasks.withType(AbstractArchiveTask).configureEach { task ->
+    duplicatesStrategy = DuplicatesStrategy.FAIL
+    reproducibleFileOrder = true
+    dirMode = 0755
+    fileMode = 0644
+  }
+}


[lucene-solr] 02/39: LUCENE-9312: Allow builds against arbitrary JVMs (squashed jira/LUCENE-9312)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 4a47c3c80885ae9ed01d061a711c31a23624160f
Author: Dawid Weiss <dw...@apache.org>
AuthorDate: Tue Jul 21 09:19:38 2020 +0200

    LUCENE-9312: Allow builds against arbitrary JVMs (squashed
    jira/LUCENE-9312)
---
 build.gradle                                     |  19 +--
 gradle/{ => documentation}/render-javadoc.gradle |  21 ++-
 gradle/help.gradle                               |   1 +
 gradle/testing/alternative-jdk-support.gradle    |  72 ++++++++++
 gradle/testing/runtime-jvm-support.gradle        |  52 -------
 help/jvms.txt                                    |  18 +++
 help/tests.txt                                   |  15 --
 lucene/CHANGES.txt                               | 174 ++++++++++++++++++++++-
 8 files changed, 285 insertions(+), 87 deletions(-)

diff --git a/build.gradle b/build.gradle
index 9c07bc7..288a6a7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -94,7 +94,7 @@ apply from: file('gradle/defaults-java.gradle')
 apply from: file('gradle/testing/defaults-tests.gradle')
 apply from: file('gradle/testing/randomization.gradle')
 apply from: file('gradle/testing/fail-on-no-tests.gradle')
-apply from: file('gradle/testing/runtime-jvm-support.gradle')
+apply from: file('gradle/testing/alternative-jdk-support.gradle')
 apply from: file('gradle/jar-manifest.gradle')
 
 // Maven publishing.
@@ -150,21 +150,6 @@ apply from: file('gradle/documentation/documentation.gradle')
 apply from: file('gradle/documentation/changes-to-html.gradle')
 apply from: file('gradle/documentation/markdown.gradle')
 apply from: file('gradle/render-javadoc.gradle')
+apply from: file('gradle/documentation/render-javadoc.gradle')
 apply from: file('gradle/hacks/findbugs.gradle')
 
-allprojects {
-  task ufclasspath {
-    doLast{
-      File ufPath = new File(project.getRootDir().getParentFile(), "unitflier/run/solr");
-      if (configurations.hasProperty('testRuntimeClasspath')) {
-        java.io.File file = new java.io.File(ufPath, project.projectDir.name + '.txt');
-        file.getParentFile().mkdirs();
-        file.write project.projectDir.toString() + "\n"
-        file << sourceSets.test.output.classesDirs.asPath + "\n"
-        file << project.projectDir.toString() + "/src/test-files" + ":" + project.projectDir.toString() + "/src/resources" + ":" + sourceSets.main.output.classesDirs.asPath + ":"
-        file << sourceSets.test.output.classesDirs.asPath + ":"
-        file << configurations.testRuntimeClasspath.asPath + "\n"
-      }
-    }
-  }
-}
diff --git a/gradle/render-javadoc.gradle b/gradle/documentation/render-javadoc.gradle
similarity index 95%
rename from gradle/render-javadoc.gradle
rename to gradle/documentation/render-javadoc.gradle
index 7fcee58..27d282b 100644
--- a/gradle/render-javadoc.gradle
+++ b/gradle/documentation/render-javadoc.gradle
@@ -1,3 +1,5 @@
+import javax.annotation.Nullable
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -150,6 +152,11 @@ class RenderJavadocTask extends DefaultTask {
 
   @Input
   def solrDocUrl = "${->project.solrDocUrl}"
+
+  @Nullable
+  @Optional
+  @Input
+  def executable
   
   /** Utility method to recursively collect all tasks with same name like this one that we depend on */
   private Set findRenderTasksInDependencies() {
@@ -165,8 +172,6 @@ class RenderJavadocTask extends DefaultTask {
 
   @TaskAction
   public void render() {
-    def javadocCmd = org.gradle.internal.jvm.Jvm.current().getJavadocExecutable()
-
     def srcDirs = srcDirSet.srcDirs.findAll { dir -> dir.exists() }
     def optionsFile = project.file("${getTemporaryDir()}/javadoc-options.txt")
     
@@ -254,6 +259,18 @@ class RenderJavadocTask extends DefaultTask {
       }
     })
 
+    def javadocCmd = {
+      if (executable == null) {
+        JavaInstallationRegistry registry = project.extensions.getByType(JavaInstallationRegistry)
+        JavaInstallation currentJvm = registry.installationForCurrentVirtualMachine.get()
+        return currentJvm.jdk.get().javadocExecutable.asFile
+      } else {
+        return project.file(executable)
+      }
+    }()
+
+    logger.info("Javadoc executable used: ${javadocCmd}")
+
     def outputFile = project.file("${getTemporaryDir()}/javadoc-output.txt")
     def result
     outputFile.withOutputStream { output ->
diff --git a/gradle/help.gradle b/gradle/help.gradle
index d76ce90..edee1c3 100644
--- a/gradle/help.gradle
+++ b/gradle/help.gradle
@@ -22,6 +22,7 @@ configure(rootProject) {
       ["Workflow", "help/workflow.txt", "Typical workflow commands."],
       ["Ant", "help/ant.txt", "Ant-gradle migration help."],
       ["Tests", "help/tests.txt", "Tests, filtering, beasting, etc."],
+      ["Jvms", "help/jvms.txt", "Using alternative or EA JVM toolchains."],
       ["Deps", "help/dependencies.txt", "Declaring, inspecting and excluding dependencies."],
       ["ForbiddenApis", "help/forbiddenApis.txt", "How to add/apply rules for forbidden APIs."],
       ["LocalSettings", "help/localSettings.txt", "Local settings, overrides and build performance tweaks."],
diff --git a/gradle/testing/alternative-jdk-support.gradle b/gradle/testing/alternative-jdk-support.gradle
new file mode 100644
index 0000000..1e69291
--- /dev/null
+++ b/gradle/testing/alternative-jdk-support.gradle
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+// This adds support for compiling and testing against a different Java runtime.
+// This is the only way to build against JVMs not yet supported by Gradle itself.
+
+JavaInstallationRegistry registry = extensions.getByType(JavaInstallationRegistry)
+
+JavaInstallation currentJvm = registry.installationForCurrentVirtualMachine.get()
+
+JavaInstallation altJvm = {
+  def runtimeJavaHome = propertyOrDefault("runtime.java.home", System.getenv('RUNTIME_JAVA_HOME'))
+  if (!runtimeJavaHome) {
+    return currentJvm
+  } else {
+    return registry.installationForDirectory(
+        layout.projectDirectory.dir(runtimeJavaHome)).get()
+  }
+}()
+
+if (!currentJvm.javaExecutable.equals(altJvm.javaExecutable)) {
+  // Set up java toolchain tasks to use the alternative Java.
+  // This is a related Gradle issue for the future:
+  // https://github.com/gradle/gradle/issues/1652
+
+  configure(rootProject) {
+    task altJvmWarning() {
+      doFirst {
+        logger.warn("""NOTE: Alternative java toolchain will be used for compilation and tests:
+  Project will use Java ${altJvm.javaVersion} from: ${altJvm.installationDirectory}
+  Gradle runs with Java ${currentJvm.javaVersion} from: ${currentJvm.installationDirectory}
+""")
+      }
+    }
+  }
+
+  // Set up toolchain-dependent tasks to use the alternative JVM.
+  allprojects {
+    // Any tests
+    tasks.withType(Test) {
+      dependsOn ":altJvmWarning"
+      executable = altJvm.javaExecutable
+    }
+
+    // Any javac compilation tasks
+    tasks.withType(JavaCompile) {
+      dependsOn ":altJvmWarning"
+      options.fork = true
+      options.forkOptions.javaHome = altJvm.installationDirectory.asFile
+    }
+
+    def javadocExecutable = altJvm.jdk.get().javadocExecutable.asFile
+    tasks.matching { it.name == "renderJavadoc" || it.name == "renderSiteJavadoc" }.all {
+      dependsOn ":altJvmWarning"
+      executable = javadocExecutable
+    }
+  }
+}
diff --git a/gradle/testing/runtime-jvm-support.gradle b/gradle/testing/runtime-jvm-support.gradle
deleted file mode 100644
index ce48b56..0000000
--- a/gradle/testing/runtime-jvm-support.gradle
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// This adds support for compiling and testing against a different Java runtime.
-// This is the only way to build against JVMs not yet supported by Gradle itself.
-
-import org.gradle.internal.jvm.Jvm
-
-def jvmForTests = {
-  def runtimeJavaHome = propertyOrDefault("runtime.java.home", System.getenv('RUNTIME_JAVA_HOME'))
-  if (!runtimeJavaHome) {
-    return Jvm.current()
-  } else {
-    return Jvm.forHome(file(runtimeJavaHome))
-  }
-}()
-def jvmGradle = Jvm.current()
-
-def differentTestJvm = (jvmGradle.javaHome.canonicalPath != jvmForTests.javaHome.canonicalPath)
-
-// Set up tasks to use the alternative Java.
-if (differentTestJvm) {
-  configure(rootProject) {
-    task testJvmWarning() {
-      doFirst {
-        logger.warn("This Java will be used for running tests: ${jvmForTests.javaExecutable}")
-      }
-    }
-  }
-
-  // Set up test tasks to use the alternative JVM.
-  allprojects {
-    tasks.withType(Test) {
-      dependsOn ":testJvmWarning"
-      executable = jvmForTests.javaExecutable
-    }
-  }
-}
\ No newline at end of file
diff --git a/help/jvms.txt b/help/jvms.txt
new file mode 100644
index 0000000..42a88d2
--- /dev/null
+++ b/help/jvms.txt
@@ -0,0 +1,18 @@
+Compiling and testing against different JVMs
+============================================
+
+By default tests are executed with the same Java Gradle is using internally.
+
+To run tests against a different Java version, define a property called
+"runtime.java.home" or define an environment variable "RUNTIME_JAVA_HOME"
+pointing at the JDK installation folder.
+
+If property is being used, it can be a system property (-D...) or a project
+property (-P...).
+
+Example:
+
+gradlew test -p lucene/test-framework --tests TestJvmInfo -Dtests.verbose=true -Druntime.java.home=/jvms/jdk14
+
+Note that an alternative JVM can also be made the "default" setting
+by adding it to (project-local) gradle.properties.
diff --git a/help/tests.txt b/help/tests.txt
index 2caef22..30b1f4a 100644
--- a/help/tests.txt
+++ b/help/tests.txt
@@ -140,18 +140,3 @@ Using these additional options will make the results more sparse, so it may be u
 to increase the top-N count:
 
 gradlew -p lucene/core test -Ptests.profile=true -Ptests.profile.count=100
-
-Testing against different JVMs
-------------------------------
-
-By default tests are executed with the same Java gradle is using internally.
-To run tests against a different Java version define a property called
-"runtime.java.home" or define an environment variable "RUNTIME_JAVA_HOME"
-pointing at the JDK installation folder.
-
-If property is used, it can be a system property (-D...) or a project
-property (-P...).
-
-Example:
-
-gradlew test -p lucene/test-framework --tests TestJvmInfo -Dtests.verbose=true -Druntime.java.home=/jvms/jdk14
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 29d5aba..d8bdf7f 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -12,7 +12,7 @@ System Requirements
 
 API Changes
 
-* LUCENE-8474: RAMDirectory and associated deprecated classes have been 
+* LUCENE-8474: RAMDirectory and associated deprecated classes have been
   removed. (Dawid Weiss)
 
 * LUCENE-3041: The deprecated Weight#extractTerms() method has been 
@@ -58,8 +58,14 @@ API Changes
 
 * LUCENE-9340: SimpleBindings#add(SortField) has been removed. (Alan Woodward)
 
+* LUCENE-9462: Fields without positions should still return MatchIterator.
+  (Alan Woodward, Dawid Weiss)
+
 Improvements
 
+* LUCENE-9463: Query match region retrieval component, passage scoring and formatting
+  for building custom highlighters. (Alan Woodward, Dawid Weiss)
+
 * LUCENE-9370: RegExp query is no longer lenient about inappropriate backslashes and
   follows the Java Pattern policy for rejecting illegal syntax.  (Mark Harwood)
 
@@ -107,6 +113,22 @@ Improvements
 
 * LUCENE-9074: Introduce Slice Executor For Dynamic Runtime Execution Of Slices (Atri Sharma)
 
+* LUCENE-9280: Add an ability for field comparators to skip non-competitive documents.
+  Creating a TopFieldCollector with totalHitsThreshold less than Integer.MAX_VALUE
+  instructs Lucene to skip non-competitive documents whenever possible. For numeric
+  sort fields the skipping functionality works when the same field is indexed both
+  with doc values and points. In this case, there is an assumption that the same data is
+  stored in these points and doc values (Mayya Sharipova, Jim Ferenczi, Adrien Grand)
+
+* LUCENE-9313: Add SerbianAnalyzer based on the snowball stemmer. (Dragan Ivanovic)
+
+* LUCENE-9449: Enhance DocComparator to provide an iterator over competitive
+  documents when searching with "after". This iterator can quickly position
+  on the desired "after" document skipping all documents and segments before
+  "after". Also redesign numeric comparators to provide skipping functionality
+  by default. (Mayya Sharipova, Jim Ferenczi)
+
+
 Bug fixes
 
 * LUCENE-8663: NRTCachingDirectory.slowFileExists may open a file while 
@@ -126,6 +148,10 @@ Bug fixes
 
 Other
 
+* LUCENE-9312: Allow gradle builds against arbitrary JVMs. (Tomoko Uchida, Dawid Weiss)
+
+* LUCENE-9391: Upgrade HPPC to 0.8.2. (Haoyu Zhai)
+
 * LUCENE-8768: Fix Javadocs build in Java 11. (Namgyu Kim)
 
 * LUCENE-9092: upgrade randomizedtesting to 2.7.5 (Dawid Weiss)
@@ -141,6 +167,120 @@ Other
 * LUCENE-9411: Fail complation on warnings, 9x gradle-only (Erick Erickson, Dawid Weiss)
   Deserves mention here as well as Lucene CHANGES.txt since it affects both.
 
+* LUCENE-9433: Remove Ant support from trunk (Erick Erickson, Uwe Schindler et.al.)
+
+* LUCENE-9215: Replace checkJavaDocs.py with doclet (Robert Muir, Dawid Weiss, Uwe Schindler)
+
+* LUCENE-9497: Integrate Error Prone, a static analysis tool during compilation (Dawid Weiss, Varun Thacker)
+
+======================= Lucene 8.7.0 =======================
+
+API Changes
+---------------------
+
+* LUCENE-9437: Lucene's facet module's DocValuesOrdinalsReader.decode method
+  is now public, making it easier for applications to decode facet
+  ordinals into their corresponding labels (Ankur)
+
+* LUCENE-9515: IndexingChain now accepts individual primitives rather than a
+  DocumentsWriterPerThread instance in order to create a new DocConsumer.
+  (Simon Willnauer)
+
+New Features
+---------------------
+
+* LUCENE-9386: RegExpQuery added case insensitive matching option. (Mark Harwood)
+
+* LUCENE-8962: Add IndexWriter merge-on-refresh feature to selectively merge
+  small segments on getReader, subject to a configurable timeout, to improve
+  search performance by reducing the number of small segments for searching. (Simon Willnauer)
+
+* LUCENE-9484: Allow sorting an index after it was created. With SortingCodecReader, existing
+  unsorted segments can be wrapped and merged into a fresh index using IndexWriter#addIndices
+  API. (Simon Willnauer, Adrien Grand)
+
+Improvements
+---------------------
+
+* LUCENE-8574: Add a new ExpressionValueSource which will enforce only one value per name
+  per hit in dependencies, ExpressionFunctionValues will no longer
+  recompute already computed values (Haoyu Zhai)
+
+* LUCENE-9416: Fix CheckIndex to print an invalid non-zero norm as
+  unsigned long when detecting corruption.
+
+* LUCENE-9440: FieldInfo#checkConsistency called twice from Lucene50(60)FieldInfosFormat#read;
+  Removed the (redundant?) assert and do these checks for real. (Yauheni Putsykovich)
+
+* LUCENE-9446: In BooleanQuery rewrite, always remove MatchAllDocsQuery filter clauses
+  when possible. (Julie Tibshirani)
+
+* LUCENE-9501: Improve how Asserting* test classes handle singleton doc values.
+
+* LUCENE-9511: Include StoredFieldsWriter in DWPT accounting to ensure that it's 
+  heap consumption is taken into account when IndexWriter stalls or should flush
+  DWPTs. (Simon Willnauer)
+
+* LUCENE-9514: Include TermVectorsWriter in DWPT accounting to ensure that it's 
+  heap consumption is taken into account when IndexWriter stalls or should flush
+  DWPTs. (Simon Willnauer)
+
+Optimizations
+---------------------
+
+* LUCENE-9395: ConstantValuesSource now shares a single DoubleValues
+  instance across all segments (Tony Xu)
+
+* LUCENE-9447, LUCENE-9486: Stored fields now get higer compression ratios on
+  highly compressible data. (Adrien Grand)
+
+* LUCENE-9373: FunctionMatchQuery now accepts a "matchCost" optimization hint.
+  (Maxim Glazkov, David Smiley)
+
+Bug Fixes
+---------------------
+
+* LUCENE-9427: Fix a regression where the unified highlighter didn't produce
+  highlights on fuzzy queries that correspond to exact matches. (Julie Tibshirani)
+
+* LUCENE-9467: Fix NRTCachingDirectory to use Directory#fileLength to check if a file
+  already exists instead of opening an IndexInput on the file which might throw a AccessDeniedException
+  in some Directory implementations. (Simon Willnauer)
+
+* LUCENE-9501: Fix a bug in IndexSortSortedNumericDocValuesRangeQuery where it could violate the
+  DocIdSetIterator contract. (Julie Tibshirani)
+
+Documentation
+---------------------
+
+* LUCENE-9424: Add a performance warning to AttributeSource.captureState javadocs (Haoyu Zhai)
+
+
+Other
+---------------------
+
+* LUCENE-9292: Refactor BKD point configuration into its own class. (Ignacio Vera)
+
+* LUCENE-9470: Make TestXYMultiPolygonShapeQueries more resilient for CONTAINS queries. (Ignacio Vera)
+
+* LUCENE-9512: Move LockFactory stress test to be a unit/integration
+  test. (Uwe Schindler, Dawid Weiss, Robert Muir)
+
+======================= Lucene 8.6.2 =======================
+
+Bug Fixes
+---------------------
+* LUCENE-9478: Prevent DWPTDeleteQueue from referencing itself and leaking memory. The queue
+  passed an implicit this reference to the next queue instance on flush which leaked about 500byte
+  of memory on each full flush, commit or getReader call. (Simon Willnauer)
+
+======================= Lucene 8.6.1 =======================
+
+Bug Fixes
+---------------------
+* LUCENE-9443: The UnifiedHighlighter was closing the underlying reader when there were multiple term-vector fields.
+  This was a regression in 8.6.0.  (David Smiley, Chris Beer)
+
 ======================= Lucene 8.6.0 =======================
 
 API Changes
@@ -182,6 +322,10 @@ New Features
 * LUCENE-7889: Grouping by range based on values from DoubleValuesSource and LongValuesSource
   (Alan Woodward)
 
+* LUCENE-8962: Add IndexWriter merge-on-commit feature to selectively merge small segments on commit,
+  subject to a configurable timeout, to improve search performance by reducing the number of small
+  segments for searching (Michael Froh, Mike Sokolov, Mike Mccandless, Simon Willnauer)
+
 Improvements
 ---------------------
 * LUCENE-9276: Use same code-path for updateDocuments and updateDocument in IndexWriter and
@@ -201,12 +345,24 @@ Improvements
 * LUCENE-9342: TotalHits' relation will be EQUAL_TO when the number of hits is lower than TopDocsColector's numHits
   (Tomás Fernández Löbbe)
 
+* LUCENE-9353: Metadata of the terms dictionary moved to its own file, with the
+  `.tmd` extension. This allows checksums of metadata to be verified when
+  opening indices and helps save seeks when opening an index. (Adrien Grand)
+
 * LUCENE-9359: SegmentInfos#readCommit now always returns a
   CorruptIndexException if the content of the file is invalid. (Adrien Grand)
   
 * LUCENE-9393: Make FunctionScoreQuery use ScoreMode.COMPLETE for creating the inner query weight when
   ScoreMode.TOP_DOCS is requested. (Tomás Fernández Löbbe)
 
+* LUCENE-9392: Make FacetsConfig.DELIM_CHAR publicly accessible (Ankur Goel))
+
+* LUCENE-9397: UniformSplit supports encodable fields metadata. (Bruno Roustant)
+
+* LUCENE-9396: Improved truncation detection for points. (Adrien Grand, Robert Muir)
+
+* LUCENE-9402: Let MultiCollector handle minCompetitiveScore (Tomás Fernández Löbbe, Adrien Grand)
+
 Optimizations
 ---------------------
 
@@ -230,6 +386,8 @@ Optimizations
 * LUCENE-9087: Build always trees with full leaves and lower the default value for maxPointsPerLeafNode to 512.
   (Ignacio Vera)
 
+* LUCENE-9148: Points now write their index in a separate file. (Adrien Grand)
+
 Bug Fixes
 ---------------------
 * LUCENE-9259: Fix wrong NGramFilterFactory argument name for preserveOriginal option (Paul Pazderski)
@@ -261,6 +419,16 @@ Bug Fixes
 * LUCENE-9362: Fix equality check in ExpressionValueSource#rewrite. This fixes rewriting of inner value sources.
   (Dmitry Emets)
 
+* LUCENE-9405: IndexWriter incorrectly calls closeMergeReaders twice when the merged segment is 100% deleted.
+  (Michael Froh, Simon Willnauer, Mike Mccandless, Mike Sokolov)
+
+* LUCENE-9400: Tessellator might build illegal polygons when several holes share the shame vertex. (Ignacio Vera)
+
+* LUCENE-9417: Tessellator might build illegal polygons when several holes share are connected to the same
+  vertex. (Ignacio Vera)
+
+* LUCENE-9418: Fix ordered intervals over interleaved terms (Alan Woodward)
+
 Other
 ---------------------
 
@@ -293,6 +461,8 @@ Other
 
 * LUCENE-9232: Fix or suppress 13 resource leak precommit warnings in lucene/replicator (Andras Salamon via Erick Erickson)
 
+* LUCENE-9398: Always keep BKD index off-heap. BKD reader does not implement Accountable any more. (Ignacio Vera)
+
 Build
 
 * Upgrade forbiddenapis to version 3.0.1.  (Uwe Schindler)
@@ -302,6 +472,8 @@ Build
 
 * LUCENE-9380: Fix auxiliary class warnings in Lucene (Erick Erickson)
 
+* LUCENE-9389: Enhance gradle logging calls validation: eliminate getMessage() (Andras Salamon via Erick Erickson)
+
 ======================= Lucene 8.5.2 =======================
 
 Optimizations


[lucene-solr] 20/39: LUCENE-9490: skip checkMissingDocsDefault on runtime Java > 14.

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 0adba5e5b15183bbbb1d8ab99a6ab47fcfa0c1f8
Author: Dawid Weiss <da...@carrotsearch.com>
AuthorDate: Sat Aug 29 17:17:24 2020 +0200

    LUCENE-9490: skip checkMissingDocsDefault on runtime Java > 14.
---
 gradle/testing/alternative-jdk-support.gradle |  4 ++++
 gradle/validation/missing-docs-check.gradle   | 13 ++++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/gradle/testing/alternative-jdk-support.gradle b/gradle/testing/alternative-jdk-support.gradle
index 1e69291..f864b64 100644
--- a/gradle/testing/alternative-jdk-support.gradle
+++ b/gradle/testing/alternative-jdk-support.gradle
@@ -32,6 +32,9 @@ JavaInstallation altJvm = {
   }
 }()
 
+// Set up root project's property.
+rootProject.ext.runtimeJava = altJvm
+
 if (!currentJvm.javaExecutable.equals(altJvm.javaExecutable)) {
   // Set up java toolchain tasks to use the alternative Java.
   // This is a related Gradle issue for the future:
@@ -63,6 +66,7 @@ if (!currentJvm.javaExecutable.equals(altJvm.javaExecutable)) {
       options.forkOptions.javaHome = altJvm.installationDirectory.asFile
     }
 
+    // Javadoc compilation.
     def javadocExecutable = altJvm.jdk.get().javadocExecutable.asFile
     tasks.matching { it.name == "renderJavadoc" || it.name == "renderSiteJavadoc" }.all {
       dependsOn ":altJvmWarning"
diff --git a/gradle/validation/missing-docs-check.gradle b/gradle/validation/missing-docs-check.gradle
index 781208a..57399ec 100644
--- a/gradle/validation/missing-docs-check.gradle
+++ b/gradle/validation/missing-docs-check.gradle
@@ -37,6 +37,18 @@ allprojects {
     task checkMissingDocsDefault(type: CheckMissingDocsTask, dependsOn: 'renderJavadoc') {
       dirs += [ project.javadoc.destinationDir ]
 
+      onlyIf {
+        def maxSupported = JavaVersion.VERSION_14
+        def runtimeVersion = runtimeJava.javaVersion
+        if (runtimeVersion > JavaVersion.VERSION_14) {
+          logger.warn("Skipping task because runtime Java version ${runtimeVersion} is " +
+              "higher than Java ${maxSupported}.")
+          return false
+        } else {
+          return true
+        }
+      }
+
       // TODO: add missing docs for all classes and bump this to level=class
       if (project.path.startsWith(":solr")) {
         level = 'package'
@@ -72,7 +84,6 @@ configure(project(':lucene:core')) {
         "org/apache/lucene/index",
         "org/apache/lucene/codecs"
     ].collect { path -> file("${project.javadoc.destinationDir}/${path}") }
-
     checkMissingDocs {
       dependsOn checkMissingDocsMethod
     }


[lucene-solr] 10/39: LUCENE-9491: Consolidate test options and improve support for dynamic… (#1807)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 72bf564e35270fb4ebdaf1cc1e2d14fae1e4e74c
Author: Dawid Weiss <dw...@apache.org>
AuthorDate: Mon Aug 31 12:20:30 2020 +0200

    LUCENE-9491: Consolidate test options and improve support for dynamic… (#1807)
    
    * LUCENE-9491: Consolidate test options and improve support for dynamically computed values.
---
 build.gradle                                       |  1 +
 gradle/defaults.gradle                             | 12 ++++
 .../hashmapAssertions.gradle}                      | 40 ++++-------
 gradle/testing/beasting.gradle                     | 12 +++-
 gradle/testing/defaults-tests.gradle               | 48 +++++++++++--
 gradle/testing/profiling.gradle                    | 50 ++++++++------
 gradle/testing/randomization.gradle                | 80 ++++++++++------------
 gradle/validation/config-file-sanity.gradle        |  2 +-
 8 files changed, 147 insertions(+), 98 deletions(-)

diff --git a/build.gradle b/build.gradle
index 9801e06..bbdc7bc 100644
--- a/build.gradle
+++ b/build.gradle
@@ -175,3 +175,4 @@ apply from: file('gradle/documentation/render-javadoc.gradle')
 
 apply from: file('gradle/hacks/findbugs.gradle')
 apply from: file('gradle/hacks/gradle.gradle')
+apply from: file('gradle/hacks/hashmapAssertions.gradle')
diff --git a/gradle/defaults.gradle b/gradle/defaults.gradle
index bf64968..5f11803 100644
--- a/gradle/defaults.gradle
+++ b/gradle/defaults.gradle
@@ -40,10 +40,22 @@ allprojects {
         result = project.getProperty(propName)
       } else if (System.properties.containsKey(propName)) {
         result = System.properties.get(propName)
+      } else if (defValue instanceof Closure) {
+        result = defValue.call()
       } else {
         result = defValue
       }
       return result
     }
+
+    // System environment variable or default.
+    envOrDefault = { envName, defValue ->
+      return Objects.requireNonNullElse(System.getenv(envName), defValue);
+    }
+
+    // Either a project, system property, environment variable or default value.
+    propertyOrEnvOrDefault = { propName, envName, defValue ->
+      return propertyOrDefault(propName, envOrDefault(envName, defValue));
+    }
   }
 }
diff --git a/gradle/defaults.gradle b/gradle/hacks/hashmapAssertions.gradle
similarity index 50%
copy from gradle/defaults.gradle
copy to gradle/hacks/hashmapAssertions.gradle
index bf64968..095726c 100644
--- a/gradle/defaults.gradle
+++ b/gradle/hacks/hashmapAssertions.gradle
@@ -15,35 +15,19 @@
  * limitations under the License.
  */
 
-allprojects {
-  apply plugin: 'base'
-
-  group "org.apache"
-
-  // Repositories to fetch dependencies from.
-  repositories {
-    mavenCentral()
-    maven {
-      url "https://maven.restlet.com"
-    }
-  }
-
-  // Artifacts will have names after full gradle project path
-  // so :solr:core will have solr-core.jar, etc.
-  project.archivesBaseName = project.path.replaceAll("^:", "").replace(':', '-')
-
-  ext {
-    // Utility method to support passing overrides via -P or -D.
-    propertyOrDefault = { propName, defValue ->
-      def result
-      if (project.hasProperty(propName)) {
-        result = project.getProperty(propName)
-      } else if (System.properties.containsKey(propName)) {
-        result = System.properties.get(propName)
-      } else {
-        result = defValue
+// Disable assertions for HashMap due to: LUCENE-8991 / JDK-8205399
+def vmName = System.getProperty("java.vm.name")
+def spec = System.getProperty("java.specification.version")
+if (vmName =~ /(?i)(hotspot|openjdk|jrockit)/ &&
+    spec =~ /^(1\.8|9|10|11)$/ &&
+    !Boolean.parseBoolean(propertyOrDefault('tests.asserts.hashmap', 'false'))) {
+  logger.info("Enabling HashMap assertions.")
+  allprojects {
+    plugins.withType(JavaPlugin) {
+      tasks.withType(Test) { task ->
+        jvmArgs("-da:java.util.HashMap")
       }
-      return result
     }
   }
 }
+
diff --git a/gradle/testing/beasting.gradle b/gradle/testing/beasting.gradle
index 1604cdb..c4b5303 100644
--- a/gradle/testing/beasting.gradle
+++ b/gradle/testing/beasting.gradle
@@ -25,6 +25,16 @@
 
 def beastingMode = gradle.startParameter.taskNames.contains("beast");
 
+allprojects {
+  plugins.withType(JavaPlugin) {
+    ext {
+      testOptions += [
+          [propName: 'tests.dups', value: 0, description: "Reiterate runs of entire test suites ('beast' task)."]
+      ]
+    }
+  }
+}
+
 if (beastingMode) {
   if (rootProject.rootSeedUserProvided) {
     logger.warn("Root randomization seed is externally provided, all duplicated runs will use the same starting seed.")
@@ -37,7 +47,7 @@ if (beastingMode) {
         group "Verification"
       }
 
-      def dups = Integer.parseInt(propertyOrDefault("tests.dups", "0"))
+      def dups = Integer.parseInt(resolvedTestOption("tests.dups"))
       if (dups <= 0) {
         throw new GradleException("Specify -Ptests.dups=[count] for beast task.")
       }
diff --git a/gradle/testing/defaults-tests.gradle b/gradle/testing/defaults-tests.gradle
index c4316d5..57b0c14 100644
--- a/gradle/testing/defaults-tests.gradle
+++ b/gradle/testing/defaults-tests.gradle
@@ -24,15 +24,49 @@ def verboseModeHookInstalled = false
 
 allprojects {
   plugins.withType(JavaPlugin) {
-    def verboseMode = Boolean.parseBoolean(propertyOrDefault("tests.verbose", "false"))
-
     project.ext {
+      // This array will collect all test options, including default values and option description.
+      // The actual values of these properties (defaults, project properties) are resolved lazily after evaluation
+      // completes.
+      // [propName: 'tests.foo', value: "bar", description: "Sets foo in tests."],
+      testOptions = [
+          // asserts, debug output.
+          [propName: 'tests.verbose', value: false, description: "Enables verbose mode (emits full test outputs immediately)."],
+          [propName: 'tests.workDir',
+           value: { -> file("${buildDir}/tmp/tests-tmp") },
+           description: "Working directory for forked test JVMs",
+           includeInReproLine: false
+          ],
+          // JVM settings
+          [propName: 'tests.minheapsize', value: "256m", description: "Minimum heap size for test JVMs"],
+          [propName: 'tests.heapsize', value: "512m", description: "Heap size for test JVMs"],
+          // Test forks
+          [propName: 'tests.jvms',
+           value: { -> ((int) Math.max(1, Math.min(Runtime.runtime.availableProcessors() / 2.0, 4.0))) },
+           description: "Number of forked test JVMs"],
+          [propName: 'tests.haltonfailure', value: true, description: "Halt processing on test failure."],
+          [propName: 'tests.jvmargs',
+           value: { -> propertyOrEnvOrDefault("tests.jvmargs", "TEST_JVM_ARGS", "-XX:TieredStopAtLevel=1") },
+           description: "Arguments passed to each forked JVM."],
+      ]
+
+      // Resolves test option's value.
+      resolvedTestOption = { propName ->
+        def option = testOptions.find { entry -> entry.propName == propName }
+        if (option == null) {
+          throw new GradleException("No such test option: " + propName)
+        }
+        return propertyOrDefault(option.propName, option.value)
+      }
+
       testsCwd = file("${buildDir}/tmp/tests-cwd")
-      testsTmpDir = file(propertyOrDefault("tests.workDir", "${buildDir}/tmp/tests-tmp"))
+      testsTmpDir = file(resolvedTestOption("tests.workDir"))
       commonDir = project(":lucene").projectDir
       commonSolrDir = project(":solr").projectDir
     }
 
+    def verboseMode = resolvedTestOption("tests.verbose").toBoolean()
+
     // If we're running in verbose mode and:
     // 1) worker count > 1
     // 2) number of 'test' tasks in the build is > 1
@@ -58,10 +92,10 @@ allprojects {
       }
       binaryResultsDirectory = file(propertyOrDefault("binaryResultsDirectory", binaryResultsDirectory))
 
-      if (verboseMode) {
+      maxParallelForks = resolvedTestOption("tests.jvms") as Integer
+      if (verboseMode && maxParallelForks != 1) {
+        logger.lifecycle("tests.jvm forced to 1 in verbose mode.")
         maxParallelForks = 1
-      } else {
-        maxParallelForks = propertyOrDefault("tests.jvms", (int) Math.max(1, Math.min(Runtime.runtime.availableProcessors() / 2.0, 4.0))) as Integer
       }
 
       workingDir testsCwd
@@ -72,6 +106,8 @@ allprojects {
 
       jvmArgs Commandline.translateCommandline(propertyOrDefault("tests.jvmargs", "-XX:TieredStopAtLevel=1 -XX:+UseParallelGC -XX:-UseBiasedLocking -DconfigurationFile=log4j2.xml -Dorg.apache.xml.dtm.DTMManager=org.apache.xml.dtm.ref.DTMManagerDefault"));
 
+      ignoreFailures = resolvedTestOption("tests.haltonfailure").toBoolean() == false
+
       systemProperty 'java.util.logging.config.file', rootProject.file("gradle/testing/defaults-tests/logging.properties")
       systemProperty 'java.awt.headless', 'true'
       systemProperty 'jdk.map.althashing.threshold', '0'
diff --git a/gradle/testing/profiling.gradle b/gradle/testing/profiling.gradle
index 01938f9..6655df7 100644
--- a/gradle/testing/profiling.gradle
+++ b/gradle/testing/profiling.gradle
@@ -19,29 +19,39 @@ import org.apache.lucene.gradle.ProfileResults;
 
 def recordings = files()
 
-if (Boolean.parseBoolean(propertyOrDefault("tests.profile", "false"))) {
-  allprojects {
-    tasks.withType(Test) {
-      jvmArgs("-XX:StartFlightRecording=dumponexit=true,maxsize=250M,settings=" + rootProject.file("gradle/testing/profiling.jfc"),
+allprojects {
+  plugins.withType(JavaPlugin) {
+    ext {
+      testOptions += [
+          [propName: 'tests.profile', value: false, description: "Enable java flight recorder profiling."]
+      ]
+    }
+
+    if (resolvedTestOption("tests.profile").toBoolean()) {
+      allprojects {
+        tasks.withType(Test) {
+          jvmArgs("-XX:StartFlightRecording=dumponexit=true,maxsize=250M,settings=" + rootProject.file("gradle/testing/profiling.jfc"),
               "-XX:+UnlockDiagnosticVMOptions",
               "-XX:+DebugNonSafepoints")
-      // delete any previous profile results
-      doFirst {
-        project.delete fileTree(dir: workingDir, include: '*.jfr')
-      }
-      doLast {
-        recordings = recordings.plus fileTree(dir: workingDir, include: '*.jfr')
+          // delete any previous profile results
+          doFirst {
+            project.delete fileTree(dir: workingDir, include: '*.jfr')
+          }
+          doLast {
+            recordings = recordings.plus fileTree(dir: workingDir, include: '*.jfr')
+          }
+        }
       }
-    }
-  }
 
-  gradle.buildFinished {
-    if (!recordings.isEmpty()) {
-      ProfileResults.printReport(recordings.getFiles().collect { it.toString() },
-                                 propertyOrDefault(ProfileResults.MODE_KEY, ProfileResults.MODE_DEFAULT) as String,
-                                 Integer.parseInt(propertyOrDefault(ProfileResults.STACKSIZE_KEY, ProfileResults.STACKSIZE_DEFAULT)),
-                                 Integer.parseInt(propertyOrDefault(ProfileResults.COUNT_KEY, ProfileResults.COUNT_DEFAULT)),
-                                 Boolean.parseBoolean(propertyOrDefault(ProfileResults.LINENUMBERS_KEY, ProfileResults.LINENUMBERS_DEFAULT)))
+      gradle.buildFinished {
+        if (!recordings.isEmpty()) {
+          ProfileResults.printReport(recordings.getFiles().collect { it.toString() },
+              propertyOrDefault(ProfileResults.MODE_KEY, ProfileResults.MODE_DEFAULT) as String,
+              Integer.parseInt(propertyOrDefault(ProfileResults.STACKSIZE_KEY, ProfileResults.STACKSIZE_DEFAULT)),
+              Integer.parseInt(propertyOrDefault(ProfileResults.COUNT_KEY, ProfileResults.COUNT_DEFAULT)),
+              Boolean.parseBoolean(propertyOrDefault(ProfileResults.LINENUMBERS_KEY, ProfileResults.LINENUMBERS_DEFAULT)))
+        }
+      }
     }
   }
-}
+}
\ No newline at end of file
diff --git a/gradle/testing/randomization.gradle b/gradle/testing/randomization.gradle
index eb539c7..570ff6a 100644
--- a/gradle/testing/randomization.gradle
+++ b/gradle/testing/randomization.gradle
@@ -60,9 +60,9 @@ allprojects {
 allprojects {
   plugins.withType(JavaPlugin) {
     ext {
-      testOptions = [
+      testOptions += [
           // seed, repetition and amplification.
-          [propName: 'tests.seed', value: "random", description: "Sets the master randomization seed."],
+          [propName: 'tests.seed', value: { -> rootSeed }, description: "Sets the master randomization seed."],
           [propName: 'tests.iters', value: null, description: "Duplicate (re-run) each test case N times."],
           [propName: 'tests.multiplier', value: 1, description: "Value multiplier for randomized tests."],
           [propName: 'tests.maxfailures', value: null, description: "Skip tests after a given number of failures."],
@@ -70,9 +70,8 @@ allprojects {
           [propName: 'tests.failfast', value: "false", description: "Stop the build early on failure.", buildOnly: true],
           // asserts, debug output.
           [propName: 'tests.asserts', value: "true", description: "Enables or disables assertions mode."],
-          [propName: 'tests.verbose', value: false, description: "Emit verbose debug information from tests."],
           [propName: 'tests.infostream', value: false, description: "Enables or disables infostream logs."],
-          [propName: 'tests.leaveTemporary', value: null, description: "Leave temporary directories after tests complete."],
+          [propName: 'tests.leaveTemporary', value: false, description: "Leave temporary directories after tests complete."],
           [propName: 'tests.useSecurityManager', value: true, description: "Control security manager in tests.", buildOnly: true],
           // component randomization
           [propName: 'tests.codec', value: "random", description: "Sets the codec tests should run with."],
@@ -88,7 +87,12 @@ allprojects {
           [propName: 'tests.weekly', value: false, description: "Enables or disables @Weekly tests."],
           [propName: 'tests.monster', value: false, description: "Enables or disables @Monster tests."],
           [propName: 'tests.awaitsfix', value: null, description: "Enables or disables @AwaitsFix tests."],
-          [propName: 'tests.file.encoding', value: "random", description: "Sets the default file.encoding on test JVM.", buildOnly: true],
+          [propName: 'tests.badapples', value: null, description: "Enables or disables @BadApple tests."],
+          [propName: 'tests.file.encoding',
+           value: { ->
+             RandomPicks.randomFrom(new Random(projectSeedLong), ["US-ASCII", "ISO-8859-1", "UTF-8"])
+           },
+           description: "Sets the default file.encoding on test JVM.", buildOnly: true],
           // test data
           [propName: 'tests.linedocsfile', value: 'europarl.lines.txt.gz', description: "Test data file path."],
           // miscellaneous; some of them very weird.
@@ -105,7 +109,11 @@ configure(allprojects.findAll {project -> project.path.startsWith(":solr") }) {
     ext {
       testOptions += [
           [propName: 'tests.luceneMatchVersion', value: baseVersion, description: "Base Lucene version."],
-          [propName: 'common-solr.dir', value: file("${commonDir}/../solr").path, description: "Solr base dir."],
+          [propName: 'common-solr.dir',
+           value: { -> file("${commonDir}/../solr").path },
+           description: "Solr base dir.",
+           includeInReproLine: false
+          ],
           [propName: 'solr.directoryFactory', value: "org.apache.solr.core.MockDirectoryFactory", description: "Solr directory factory."],
           [propName: 'tests.src.home', value: null, description: "See SOLR-14023."],
           [propName: 'solr.tests.use.numeric.points', value: null, description: "Point implementation to use (true=numerics, false=trie)."],
@@ -121,23 +129,15 @@ allprojects {
       ext.testOptionsResolved = testOptions.findAll { opt ->
         propertyOrDefault(opt.propName, opt.value) != null
       }.collectEntries { opt ->
-        [(opt.propName): Objects.toString(propertyOrDefault(opt.propName, opt.value))]
-      }
-
-      // These are not official options or dynamically seed-derived options.
-      if (testOptionsResolved['tests.file.encoding'] == 'random') {
-        testOptionsResolved['tests.file.encoding'] = RandomPicks.randomFrom(
-            new Random(projectSeedLong), [
-                "US-ASCII", "ISO-8859-1", "UTF-8"
-            ])
-      }
-
-      if (testOptionsResolved['tests.seed'] == 'random') {
-        testOptionsResolved['tests.seed'] = rootSeed
+        [(opt.propName): Objects.toString(resolvedTestOption(opt.propName))]
       }
 
       // Compute the "reproduce with" string.
       ext.testOptionsForReproduceLine = testOptions.findAll { opt ->
+        if (opt["includeInReproLine"] == false) {
+          return false
+        }
+
         def defValue = Objects.toString(opt.value, null)
         def value = testOptionsResolved[opt.propName]
         return defValue != value
@@ -152,14 +152,19 @@ allprojects {
          "tests.leavetmpdir",
          "solr.test.leavetmpdir",
       ].find { prop ->
-        Boolean.parseBoolean(propertyOrDefault(prop, "false"))
+        def v = Boolean.parseBoolean(propertyOrDefault(prop, "false"))
+        if (v) {
+          logger.lifecycle("Update your code to use the official 'tests.leaveTemporary' option (you used '${prop}').")
+        }
+        return v
       }) {
         testOptionsResolved['tests.leaveTemporary'] = "true"
       }
 
       // Append resolved test properties to the test task.
       tasks.withType(Test) { task ->
-        // TODO: we could remove opts with "buildOnly: true" (?)
+        // TODO: we could remove some options that are only relevant to the build environment
+        // and not the test JVM itself.
         systemProperties testOptionsResolved
 
         if (Boolean.parseBoolean(testOptionsResolved['tests.asserts'])) {
@@ -215,33 +220,24 @@ allprojects {
         println "Test options for project ${project.path} and seed \"${rootSeed}\":"
 
         testOptions.sort { a, b -> a.propName.compareTo(b.propName) }.each { opt ->
-          def defValue = Objects.toString(opt.value, null)
+          def defValue
+          def computedValue = false
+          if (opt.value instanceof Closure) {
+            defValue = Objects.toString(opt.value(), null)
+            computedValue = true
+          } else {
+            defValue = Objects.toString(opt.value, null)
+          }
+
           def value = testOptionsResolved[opt.propName]
           println String.format(Locale.ROOT,
-              "%s%-23s = %-8s # %s",
-              (defValue != value ? "! " : "  "),
+              "%s%-24s = %-8s # %s",
+              (defValue != value ? "! " : computedValue ? "C " : "  "),
               opt.propName,
               value,
-              (defValue != value ? "(!= default: ${defValue}) " : "") + opt.description)
+              (computedValue ? "(!= default: computed) " : (defValue != value ? "(!= default: ${defValue}) " : "")) + opt.description)
         }
       }
     }
   }
 }
-
-// Disable assertions for HashMap due to: LUCENE-8991 / JDK-8205399
-def vmName = System.getProperty("java.vm.name")
-def spec = System.getProperty("java.specification.version")
-if (vmName =~ /(?i)(hotspot|openjdk|jrockit)/ &&
-    spec =~ /^(1\.8|9|10|11)$/ &&
-    !Boolean.parseBoolean(propertyOrDefault('tests.asserts.hashmap', 'false'))) {
-  logger.debug("Enabling HashMap assertions.")
-  allprojects {
-    plugins.withType(JavaPlugin) {
-      tasks.withType(Test) { task ->  
-        jvmArgs("-da:java.util.HashMap")
-      }
-    }
-  }
-}
-
diff --git a/gradle/validation/config-file-sanity.gradle b/gradle/validation/config-file-sanity.gradle
index e7ae048..30f6391 100644
--- a/gradle/validation/config-file-sanity.gradle
+++ b/gradle/validation/config-file-sanity.gradle
@@ -20,7 +20,7 @@
 configure(project(":solr")) {
   task validateConfigFileSanity() {
     doFirst {
-      def matchVersion = project(":solr:core").testOptionsResolved['tests.luceneMatchVersion']
+      def matchVersion = project(":solr:core").resolvedTestOption('tests.luceneMatchVersion')
       if (!matchVersion) {
         throw new GradleException("tests.luceneMatchVersion not defined?")
       }


[lucene-solr] 14/39: LUCENE-9497: Integerate Error Prone ( Static Analysis Tool ) during compilation (#1816)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 17a3ba723ae0041e608103523201a381d4ebc2e8
Author: Varun Thacker <vt...@users.noreply.github.com>
AuthorDate: Mon Sep 7 14:42:48 2020 -0700

    LUCENE-9497: Integerate Error Prone ( Static Analysis Tool ) during compilation (#1816)
    
    LUCENE-9497:  Integrate Error Prone, a static analysis tool during compilation
---
 build.gradle                                       |   2 +
 gradle/defaults-java.gradle                        |   5 +-
 gradle/hacks/findbugs.gradle                       |   6 +-
 gradle/validation/error-prone.gradle               | 149 +++++++++++++++++++++
 lucene/CHANGES.txt                                 |   5 +
 .../org/apache/lucene/analysis/CharArrayMap.java   |   1 +
 versions.props                                     |   1 +
 7 files changed, 166 insertions(+), 3 deletions(-)

diff --git a/build.gradle b/build.gradle
index d20deeb..f01045b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -24,6 +24,7 @@ plugins {
   id "org.owasp.dependencycheck" version "5.3.0"
   id 'de.thetaphi.forbiddenapis' version '3.0.1' apply false
   id "de.undercouch.download" version "4.0.2" apply false
+  id "net.ltgt.errorprone" version "1.2.1" apply false
 }
 
 apply from: file('gradle/defaults.gradle')
@@ -127,6 +128,7 @@ apply from: file('gradle/ide/intellij-idea.gradle')
 apply from: file('gradle/ide/eclipse.gradle')
 
 // Validation tasks
+apply from: file('gradle/validation/error-prone.gradle')
 apply from: file('gradle/validation/precommit.gradle')
 apply from: file('gradle/validation/forbidden-apis.gradle')
 apply from: file('gradle/validation/jar-checks.gradle')
diff --git a/gradle/defaults-java.gradle b/gradle/defaults-java.gradle
index e739a19..9495268 100644
--- a/gradle/defaults-java.gradle
+++ b/gradle/defaults-java.gradle
@@ -39,8 +39,11 @@ allprojects {
         "-Xdoclint:-missing",
         "-Xdoclint:-accessibility",
         "-proc:none",  // proc:none was added because of LOG4J2-1925 / JDK-8186647
-        "-Werror",
       ]
+
+      if (propertyOrDefault("javac.failOnWarnings", true).toBoolean()) {
+        options.compilerArgs += "-Werror"
+      }
     }
   }
 }
diff --git a/gradle/hacks/findbugs.gradle b/gradle/hacks/findbugs.gradle
index bdbdb7e..f228738 100644
--- a/gradle/hacks/findbugs.gradle
+++ b/gradle/hacks/findbugs.gradle
@@ -16,12 +16,14 @@
  */ 
 
 // See LUCENE-9411. This hack adds compile-time only dependencies
-// on findbugs annotations. Otherwise javac generates odd warnings about missing
+// on findbugs and error_prone annotations. Otherwise javac generates odd warnings about missing
 // type information.
 
 configure([project(":solr:core"),
            project(":solr:solrj"),
-           project(":solr:contrib:prometheus-exporter")]) {
+           project(":solr:contrib:prometheus-exporter"),
+           project(":solr:test-framework"),
+           project(":solr:contrib:analytics")]) {
   plugins.withType(JavaPlugin) {
     dependencies {
       // Use versionless variants because these libraries are in versions.lock.
diff --git a/gradle/validation/error-prone.gradle b/gradle/validation/error-prone.gradle
new file mode 100644
index 0000000..d91fbb4
--- /dev/null
+++ b/gradle/validation/error-prone.gradle
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+allprojects { prj ->
+  plugins.withType(JavaPlugin) {
+    prj.apply plugin: 'net.ltgt.errorprone'
+
+    dependencies {
+      errorprone("com.google.errorprone:error_prone_core")
+    }
+
+    tasks.withType(JavaCompile) { task ->
+      options.errorprone.disableWarningsInGeneratedCode = true
+      options.errorprone.errorproneArgs = [
+          // test
+          '-Xep:ExtendingJUnitAssert:OFF',
+          '-Xep:UseCorrectAssertInTests:OFF',
+          '-Xep:DefaultPackage:OFF',
+          '-Xep:FloatingPointLiteralPrecision:OFF',
+          '-Xep:CatchFail:OFF',
+          '-Xep:TryFailThrowable:OFF',
+          '-Xep:MathAbsoluteRandom:OFF',
+          '-Xep:AssertionFailureIgnored:OFF',
+          '-Xep:JUnit4TestNotRun:OFF',
+          '-Xep:FallThrough:OFF',
+          '-Xep:CatchAndPrintStackTrace:OFF',
+          '-Xep:ToStringReturnsNull:OFF',
+          '-Xep:ArrayAsKeyOfSetOrMap:OFF',
+          '-Xep:StaticAssignmentInConstructor:OFF',
+          '-Xep:SelfAssignment:OFF',
+          '-Xep:InvalidPatternSyntax:OFF',
+          '-Xep:MissingFail:OFF',
+          '-Xep:LossyPrimitiveCompare:OFF',
+          '-Xep:ComparableType:OFF',
+          '-Xep:InfiniteRecursion:OFF',
+          '-Xep:MisusedDayOfYear:OFF',
+          '-Xep:FloatingPointAssertionWithinEpsilon:OFF',
+
+          '-Xep:ThrowNull:OFF',
+          '-Xep:StaticGuardedByInstance:OFF',
+          '-Xep:ArrayHashCode:OFF',
+          '-Xep:ArrayEquals:OFF',
+          '-Xep:IdentityBinaryExpression:OFF',
+          '-Xep:ComplexBooleanConstant:OFF',
+          '-Xep:ComplexBooleanConstant:OFF',
+          '-Xep:StreamResourceLeak:OFF',
+          '-Xep:UnnecessaryLambda:OFF',
+          '-Xep:ObjectToString:OFF',
+          '-Xep:URLEqualsHashCode:OFF',
+          '-Xep:DoubleBraceInitialization:OFF',
+          '-Xep:ShortCircuitBoolean:OFF',
+          '-Xep:InputStreamSlowMultibyteRead:OFF',
+          '-Xep:NonCanonicalType:OFF',
+          '-Xep:CollectionIncompatibleType:OFF',
+          '-Xep:TypeParameterShadowing:OFF',
+          '-Xep:ThreadJoinLoop:OFF',
+          '-Xep:MutableConstantField:OFF',
+          '-Xep:ReturnValueIgnored:OFF',
+          '-Xep:CollectionIncompatibleType:OFF',
+          '-Xep:SameNameButDifferent:OFF',
+          '-Xep:InvalidParam:OFF',
+          '-Xep:CompareToZero:OFF',
+          '-Xep:DoubleCheckedLocking:OFF',
+          '-Xep:BadShiftAmount:OFF',
+          '-Xep:CollectionUndefinedEquality:OFF',
+          '-Xep:UnescapedEntity:OFF',
+          '-Xep:BoxedPrimitiveEquality:OFF',
+          '-Xep:LogicalAssignment:OFF',
+          '-Xep:DoubleCheckedLocking:OFF',
+          '-Xep:AmbiguousMethodReference:OFF',
+          '-Xep:FormatString:OFF',
+          '-Xep:InstanceOfAndCastMatchWrongType:OFF',
+          '-Xep:ModifyCollectionInEnhancedForLoop:OFF',
+          '-Xep:JavaLangClash:OFF',
+          '-Xep:TypeParameterUnusedInFormals:OFF',
+          '-Xep:UnusedNestedClass:OFF',
+          '-Xep:OverrideThrowableToString:OFF',
+          '-Xep:FutureReturnValueIgnored:OFF',
+          '-Xep:BadInstanceof:OFF',
+          '-Xep:UnusedNestedClass:OFF',
+          '-Xep:OverrideThrowableToString:OFF',
+          '-Xep:EqualsIncompatibleType:OFF',
+          '-Xep:ByteBufferBackingArray:OFF',
+          '-Xep:ByteBufferBackingArray:OFF',
+          '-Xep:UnusedMethod:OFF',
+          '-Xep:ObjectsHashCodePrimitive:OFF',
+          '-Xep:ObjectsHashCodePrimitive:OFF',
+          '-Xep:UnnecessaryAnonymousClass:OFF',
+          '-Xep:BoxedPrimitiveConstructor:OFF',
+          '-Xep:ArgumentSelectionDefectChecker:OFF',
+          '-Xep:StringSplitter:OFF',
+          '-Xep:MixedMutabilityReturnType:OFF',
+          '-Xep:EqualsUnsafeCast:OFF',
+          '-Xep:OperatorPrecedence:OFF',
+          '-Xep:HidingField:OFF',
+          '-Xep:ThreadPriorityCheck:OFF',
+          '-Xep:InlineFormatString:OFF',
+          '-Xep:EqualsUnsafeCast:OFF',
+          '-Xep:UnsynchronizedOverridesSynchronized:OFF',
+          '-Xep:OperatorPrecedence:OFF',
+          '-Xep:ArrayToString:OFF',
+          '-Xep:ClassCanBeStatic:OFF',
+          '-Xep:InvalidInlineTag:OFF',
+          '-Xep:EmptyCatch:OFF',
+          '-Xep:UnnecessaryParentheses:OFF',
+          '-Xep:AlmostJavadoc:OFF',
+          '-Xep:Finally:OFF',
+          '-Xep:ImmutableEnumChecker:OFF',
+          '-Xep:NonAtomicVolatileUpdate:OFF',
+          '-Xep:MutablePublicArray:OFF',
+          '-Xep:LockNotBeforeTry:OFF',
+          '-Xep:WaitNotInLoop:OFF',
+          '-Xep:UndefinedEquals:OFF',
+          '-Xep:JdkObsolete:OFF',
+          '-Xep:NarrowingCompoundAssignment:OFF',
+          '-Xep:InconsistentCapitalization:OFF',
+          '-Xep:IntLongMath:OFF',
+          '-Xep:SynchronizeOnNonFinalField:OFF',
+          '-Xep:ThreadLocalUsage:OFF',
+          '-Xep:ProtectedMembersInFinalClass:OFF',
+          '-Xep:BadImport:OFF',
+          '-Xep:InconsistentHashCode:OFF',
+          '-Xep:MissingOverride:OFF',
+          '-Xep:EqualsGetClass:OFF',
+          '-Xep:PublicConstructorForAbstractClass:OFF',
+          '-Xep:EscapedEntity:OFF',
+          '-Xep:ModifiedButNotUsed:OFF',
+          '-Xep:ReferenceEquality:OFF',
+          '-Xep:InvalidBlockTag:OFF',
+          '-Xep:MissingSummary:OFF',
+          '-Xep:UnusedVariable:OFF'
+      ]
+    }
+  }
+}
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index d8bdf7f..6418f4d 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -255,6 +255,11 @@ Documentation
 
 * LUCENE-9424: Add a performance warning to AttributeSource.captureState javadocs (Haoyu Zhai)
 
+Other
+---------------------
+
+* LUCENE-9497: Integrate Error Prone, a static analysis tool during compilation (Dawid Weiss, Varun Thacker)
+
 
 Other
 ---------------------
diff --git a/lucene/core/src/java/org/apache/lucene/analysis/CharArrayMap.java b/lucene/core/src/java/org/apache/lucene/analysis/CharArrayMap.java
index cad339b..ac88886 100644
--- a/lucene/core/src/java/org/apache/lucene/analysis/CharArrayMap.java
+++ b/lucene/core/src/java/org/apache/lucene/analysis/CharArrayMap.java
@@ -523,6 +523,7 @@ public class CharArrayMap<V> extends AbstractMap<Object,V> {
    * @throws NullPointerException
    *           if the given map is <code>null</code>.
    */
+  @SuppressWarnings("ReferenceEquality")
   public static <V> CharArrayMap<V> unmodifiableMap(CharArrayMap<V> map) {
     if (map == null)
       throw new NullPointerException("Given map is null");
diff --git a/versions.props b/versions.props
index 5477dfd..dea7c34 100644
--- a/versions.props
+++ b/versions.props
@@ -11,6 +11,7 @@ com.fasterxml.woodstox:woodstox-core:6.0.3
 com.github.ben-manes.caffeine:caffeine=2.8.4
 com.github.virtuald:curvesapi=1.06
 com.github.zafarkhaja:java-semver=0.9.0
+com.google.errorprone:*=2.4.0
 com.google.guava:guava=25.1-jre
 com.google.protobuf:protobuf-java=3.11.0
 com.google.re2j:re2j=1.2


[lucene-solr] 19/39: LUCENE-9441: Fix ant-specific Javadoc links in accordance with Gradle build

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 2d32436dea42bc5c768fca10a8e8de9f7c69bb05
Author: Tomoko Uchida <to...@gmail.com>
AuthorDate: Sat Aug 29 22:28:03 2020 +0900

    LUCENE-9441: Fix ant-specific Javadoc links in accordance with Gradle build
---
 gradle/validation/check-broken-links.gradle              |  5 ++---
 .../java/org/apache/lucene/collation/package-info.java   |  2 +-
 .../src/java/org/apache/lucene/analysis/Analyzer.java    | 16 ++++++++--------
 .../java/org/apache/lucene/analysis/package-info.java    |  8 ++++----
 lucene/core/src/java/overview.html                       |  4 ++--
 lucene/demo/src/java/overview.html                       |  2 +-
 6 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/gradle/validation/check-broken-links.gradle b/gradle/validation/check-broken-links.gradle
index ed83a86..29dcd90 100644
--- a/gradle/validation/check-broken-links.gradle
+++ b/gradle/validation/check-broken-links.gradle
@@ -24,12 +24,11 @@ configure(rootProject) {
     dependsOn ':solr:checkBrokenLinks'
   }
 }
+
 configure(subprojects.findAll { it.path in [':lucene', ':solr'] }) {
   task checkBrokenLinks(type: CheckBrokenLinksTask, 'dependsOn': 'documentation')
 
-  // TODO: uncomment this line after fixing all broken links.
-  // (we can't fix the cross-project links until ant build is disabled.)
-  // check.dependsOn checkBrokenLinks
+  check.dependsOn checkBrokenLinks
 }
 
 class CheckBrokenLinksTask extends DefaultTask {
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/collation/package-info.java b/lucene/analysis/common/src/java/org/apache/lucene/collation/package-info.java
index 5b83ea5..c79b58c 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/collation/package-info.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/collation/package-info.java
@@ -145,7 +145,7 @@
  *   </li>
  * </ol> 
  * <p>
- *   <code>ICUCollationKeyAnalyzer</code>, available in the <a href="{@docRoot}/../analyzers-icu/overview-summary.html">icu analysis module</a>,
+ *   <code>ICUCollationKeyAnalyzer</code>, available in the <a href="{@docRoot}/../icu/overview-summary.html">icu analysis module</a>,
  *   uses ICU4J's <code>Collator</code>, which 
  *   makes its version available, thus allowing collation to be versioned
  *   independently from the JVM.  <code>ICUCollationKeyAnalyzer</code> is also 
diff --git a/lucene/core/src/java/org/apache/lucene/analysis/Analyzer.java b/lucene/core/src/java/org/apache/lucene/analysis/Analyzer.java
index b9a798b..2749c1c 100644
--- a/lucene/core/src/java/org/apache/lucene/analysis/Analyzer.java
+++ b/lucene/core/src/java/org/apache/lucene/analysis/Analyzer.java
@@ -64,19 +64,19 @@ import org.apache.lucene.util.Version;
  * <p>
  * For some concrete implementations bundled with Lucene, look in the analysis modules:
  * <ul>
- *   <li><a href="{@docRoot}/../analyzers-common/overview-summary.html">Common</a>:
+ *   <li><a href="{@docRoot}/../analysis/common/overview-summary.html">Common</a>:
  *       Analyzers for indexing content in different languages and domains.
- *   <li><a href="{@docRoot}/../analyzers-icu/overview-summary.html">ICU</a>:
+ *   <li><a href="{@docRoot}/../analysis/icu/overview-summary.html">ICU</a>:
  *       Exposes functionality from ICU to Apache Lucene. 
- *   <li><a href="{@docRoot}/../analyzers-kuromoji/overview-summary.html">Kuromoji</a>:
+ *   <li><a href="{@docRoot}/../analysis/kuromoji/overview-summary.html">Kuromoji</a>:
  *       Morphological analyzer for Japanese text.
- *   <li><a href="{@docRoot}/../analyzers-morfologik/overview-summary.html">Morfologik</a>:
+ *   <li><a href="{@docRoot}/../analysis/morfologik/overview-summary.html">Morfologik</a>:
  *       Dictionary-driven lemmatization for the Polish language.
- *   <li><a href="{@docRoot}/../analyzers-phonetic/overview-summary.html">Phonetic</a>:
+ *   <li><a href="{@docRoot}/../analysis/phonetic/overview-summary.html">Phonetic</a>:
  *       Analysis for indexing phonetic signatures (for sounds-alike search).
- *   <li><a href="{@docRoot}/../analyzers-smartcn/overview-summary.html">Smart Chinese</a>:
+ *   <li><a href="{@docRoot}/../analysis/smartcn/overview-summary.html">Smart Chinese</a>:
  *       Analyzer for Simplified Chinese, which indexes words.
- *   <li><a href="{@docRoot}/../analyzers-stempel/overview-summary.html">Stempel</a>:
+ *   <li><a href="{@docRoot}/../analysis/stempel/overview-summary.html">Stempel</a>:
  *       Algorithmic Stemmer for the Polish Language.
  * </ul>
  *
@@ -103,7 +103,7 @@ public abstract class Analyzer implements Closeable {
    * <p>
    * NOTE: if you just want to reuse on a per-field basis, it's easier to
    * use a subclass of {@link AnalyzerWrapper} such as 
-   * <a href="{@docRoot}/../analyzers-common/org/apache/lucene/analysis/miscellaneous/PerFieldAnalyzerWrapper.html">
+   * <a href="{@docRoot}/../analysis/common/org/apache/lucene/analysis/miscellaneous/PerFieldAnalyzerWrapper.html">
    * PerFieldAnalyerWrapper</a> instead.
    */
   public Analyzer(ReuseStrategy reuseStrategy) {
diff --git a/lucene/core/src/java/org/apache/lucene/analysis/package-info.java b/lucene/core/src/java/org/apache/lucene/analysis/package-info.java
index b7e752c..83736ae 100644
--- a/lucene/core/src/java/org/apache/lucene/analysis/package-info.java
+++ b/lucene/core/src/java/org/apache/lucene/analysis/package-info.java
@@ -158,10 +158,10 @@
  *   supplies a large family of <code>Analyzer</code> classes that deliver useful
  *   analysis chains. The most common of these is the <a href="{@docRoot}/org/apache/lucene/analysis/standard/StandardAnalyzer.html">StandardAnalyzer</a>.
  *   Many applications will have a long and industrious life with nothing more
- *   than the <code>StandardAnalyzer</code>. The <a href="{@docRoot}/../analyzers-common/overview-summary.html">analyzers-common</a>
+ *   than the <code>StandardAnalyzer</code>. The <a href="{@docRoot}/../analysis/common/overview-summary.html">analyzers-common</a>
  *   library provides many pre-existing analyzers for various languages.
  *   The analysis-common library also allows to configure a custom Analyzer without subclassing using the
- *   <a href="{@docRoot}/../analyzers-common/org/apache/lucene/analysis/custom/CustomAnalyzer.html">CustomAnalyzer</a>
+ *   <a href="{@docRoot}/../analysis/common/org/apache/lucene/analysis/custom/CustomAnalyzer.html">CustomAnalyzer</a>
  *   class.
  * </p>
  * <p>
@@ -170,7 +170,7 @@
  *   all under the 'analysis' directory of the distribution. Some of
  *   these support particular languages, others integrate external
  *   components. The 'common' subdirectory has some noteworthy
- *  general-purpose analyzers, including the <a href="{@docRoot}/../analyzers-common/org/apache/lucene/analysis/miscellaneous/PerFieldAnalyzerWrapper.html">PerFieldAnalyzerWrapper</a>. Most <code>Analyzer</code>s perform the same operation on all
+ *  general-purpose analyzers, including the <a href="{@docRoot}/../analysis/common/org/apache/lucene/analysis/miscellaneous/PerFieldAnalyzerWrapper.html">PerFieldAnalyzerWrapper</a>. Most <code>Analyzer</code>s perform the same operation on all
  *  {@link org.apache.lucene.document.Field}s.  The PerFieldAnalyzerWrapper can be used to associate a different <code>Analyzer</code> with different
  *  {@link org.apache.lucene.document.Field}s. There is a great deal of
  *  functionality in the analysis area, you should study it carefully to
@@ -253,7 +253,7 @@
  *   Tokenizer, and TokenFilter(s) <i>(optional)</i> &mdash; or components you
  *   create, or a combination of existing and newly created components.  Before
  *   pursuing this approach, you may find it worthwhile to explore the
- *   <a href="{@docRoot}/../analyzers-common/overview-summary.html">analyzers-common</a> library and/or ask on the 
+ *   <a href="{@docRoot}/../analysis/common/overview-summary.html">analyzers-common</a> library and/or ask on the
  *   <a href="http://lucene.apache.org/core/discussion.html">java-user@lucene.apache.org mailing list</a> first to see if what you
  *   need already exists. If you are still committed to creating your own
  *   Analyzer, have a look at the source code of any one of the many samples
diff --git a/lucene/core/src/java/overview.html b/lucene/core/src/java/overview.html
index b8f21e9..ddccf1d 100644
--- a/lucene/core/src/java/overview.html
+++ b/lucene/core/src/java/overview.html
@@ -72,8 +72,8 @@ an enumeration of token {@link org.apache.lucene.util.Attribute Attribute}s.&nbs
 A TokenStream can be composed by applying {@link org.apache.lucene.analysis.TokenFilter TokenFilter}s
 to the output of a {@link org.apache.lucene.analysis.Tokenizer Tokenizer}.&nbsp;
 Tokenizers and TokenFilters are strung together and applied with an {@link org.apache.lucene.analysis.Analyzer Analyzer}.&nbsp;
-<a href="../analyzers-common/overview-summary.html">analyzers-common</a> provides a number of Analyzer implementations, including 
-<a href="../analyzers-common/org/apache/lucene/analysis/core/StopAnalyzer.html">StopAnalyzer</a>
+<a href="../analysis/common/overview-summary.html">analyzers-common</a> provides a number of Analyzer implementations, including
+<a href="../analysis/common/org/apache/lucene/analysis/core/StopAnalyzer.html">StopAnalyzer</a>
 and the grammar-based <a href="org/apache/lucene/analysis/standard/StandardAnalyzer.html">StandardAnalyzer</a>.</li>
 
 <li>
diff --git a/lucene/demo/src/java/overview.html b/lucene/demo/src/java/overview.html
index 8f1a08a..d3a1c12 100644
--- a/lucene/demo/src/java/overview.html
+++ b/lucene/demo/src/java/overview.html
@@ -151,7 +151,7 @@ have less value for searching. It should be noted that there are different
 rules for every language, and you should use the proper analyzer for each.
 Lucene currently provides Analyzers for a number of different languages (see
 the javadocs under <a href=
-"../analyzers-common/overview-summary.html">lucene/analysis/common/src/java/org/apache/lucene/analysis</a>).</p>
+"../analysis/common/overview-summary.html">lucene/analysis/common/src/java/org/apache/lucene/analysis</a>).</p>
 <p>The <span class="codefrag">IndexWriterConfig</span> instance holds all
 configuration for <span class="codefrag">IndexWriter</span>. For example, we
 set the <span class="codefrag">OpenMode</span> to use here based on the value


[lucene-solr] 09/39: LUCENE-9474: make externalTool a function and add a build-stopping message on Windows for snowball generator.

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 4f2ef00efa234f69e9265ceee06442bc7ff82a98
Author: Dawid Weiss <da...@carrotsearch.com>
AuthorDate: Sun Aug 30 17:10:18 2020 +0200

    LUCENE-9474: make externalTool a function and add a build-stopping message on Windows for snowball generator.
---
 build.gradle                                | 12 ++++++------
 gradle/documentation/changes-to-html.gradle |  2 +-
 gradle/generation/jflex.gradle              |  2 +-
 gradle/generation/snowball.gradle           |  8 +++++++-
 gradle/generation/util.gradle               |  4 ++--
 gradle/validation/check-broken-links.gradle |  5 +----
 gradle/validation/missing-docs-check.gradle |  2 +-
 7 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/build.gradle b/build.gradle
index 4c8209a..9801e06 100644
--- a/build.gradle
+++ b/build.gradle
@@ -90,12 +90,12 @@ ext {
       "flexmark": "0.61.24",
   ]
   
-  // read some external tool locations from system props
-  externalToolExecutables = [
-      "python3": propertyOrDefault('python3.exe', 'python3'),
-      "python2": propertyOrDefault('python2.exe', 'python2'),
-      "perl": propertyOrDefault('perl.exe', 'perl'),
-  ]
+  // Allow definiting external tool locations using system props.
+  externalTool = { name ->
+    def resolved = propertyOrDefault("${name}.exe", name as String)
+    logger.info("External tool '${name}' resolved to: ${resolved}")
+    return resolved
+  }
 }
 
 // Include smaller chunks configuring dedicated build areas.
diff --git a/gradle/documentation/changes-to-html.gradle b/gradle/documentation/changes-to-html.gradle
index 5f56532..b49ae93 100644
--- a/gradle/documentation/changes-to-html.gradle
+++ b/gradle/documentation/changes-to-html.gradle
@@ -54,7 +54,7 @@ class ChangesToHtmlTask extends DefaultTask {
   def toHtml(File versionsFile) {
     def output = new ByteArrayOutputStream()
     def result = project.exec {
-      executable project.externalToolExecutables["perl"]
+      executable project.externalTool("perl")
       standardInput changesFile.newInputStream()
       standardOutput project.file("${targetDir.get().getAsFile()}/Changes.html").newOutputStream()
       errorOutput = output
diff --git a/gradle/generation/jflex.gradle b/gradle/generation/jflex.gradle
index 1f5feb2..e7c65df 100644
--- a/gradle/generation/jflex.gradle
+++ b/gradle/generation/jflex.gradle
@@ -149,7 +149,7 @@ configure(project(":lucene:analysis:common")) {
       def target = file('src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex')
       target.withOutputStream { output ->
         project.exec {
-          executable = project.externalToolExecutables["python2"]
+          executable = project.externalTool("python2")
           workingDir = target.parentFile
           standardOutput = output
           args += [
diff --git a/gradle/generation/snowball.gradle b/gradle/generation/snowball.gradle
index b2b6882..b7b37c4 100644
--- a/gradle/generation/snowball.gradle
+++ b/gradle/generation/snowball.gradle
@@ -15,6 +15,8 @@
  * limitations under the License.
  */
 
+import org.apache.tools.ant.taskdefs.condition.Os
+
 apply plugin: "de.undercouch.download"
 
 configure(rootProject) {
@@ -99,8 +101,12 @@ configure(project(":lucene:analysis:common")) {
     dependsOn downloadSnowballData
 
     doLast {
+      if (Os.isFamily(Os.FAMILY_WINDOWS)) {
+        throw GradleException("Snowball generation does not work on Windows, use a platform where bash is available.")
+      }
+
       project.exec {
-        executable "bash" // TODO: does not work with windows, use project.externalToolExecutables[] instead
+        executable "bash"
         args = [snowballScript, snowballStemmerDir, snowballWebsiteDir, snowballDataDir, projectDir]
       }
     }
diff --git a/gradle/generation/util.gradle b/gradle/generation/util.gradle
index d1a3c24..36ad86b 100644
--- a/gradle/generation/util.gradle
+++ b/gradle/generation/util.gradle
@@ -57,7 +57,7 @@ configure(project(":lucene:core")) {
         logger.lifecycle("Executing: ${prog} in ${targetDir}")
         project.exec {
           workingDir targetDir
-          executable project.externalToolExecutables["python3"]
+          executable project.externalTool("python3")
           args = ['-B', "${prog}"]
         }
       }
@@ -82,7 +82,7 @@ configure(project(":lucene:core")) {
         ['True', 'False'].each { transpose ->
           project.exec {
             workingDir targetDir
-            executable project.externalToolExecutables["python3"]
+            executable project.externalTool("python3")
             args = ['-B', 'createLevAutomata.py', num, transpose, "${momanDir}/finenight/python"]
           }
         }
diff --git a/gradle/validation/check-broken-links.gradle b/gradle/validation/check-broken-links.gradle
index 2810475..ed83a86 100644
--- a/gradle/validation/check-broken-links.gradle
+++ b/gradle/validation/check-broken-links.gradle
@@ -16,7 +16,6 @@
  */
 
 configure(rootProject) {
-
   task checkBrokenLinks {
     group 'Verification'
     description 'Check broken links in the entire documentation'
@@ -24,10 +23,8 @@ configure(rootProject) {
     dependsOn ':lucene:checkBrokenLinks'
     dependsOn ':solr:checkBrokenLinks'
   }
-
 }
 configure(subprojects.findAll { it.path in [':lucene', ':solr'] }) {
-
   task checkBrokenLinks(type: CheckBrokenLinksTask, 'dependsOn': 'documentation')
 
   // TODO: uncomment this line after fixing all broken links.
@@ -52,7 +49,7 @@ class CheckBrokenLinksTask extends DefaultTask {
     def result
     outputFile.withOutputStream { output ->
       result = project.exec {
-        executable project.externalToolExecutables["python3"]
+        executable project.externalTool("python3")
         ignoreExitValue = true
         standardOutput = output
         errorOutput = output
diff --git a/gradle/validation/missing-docs-check.gradle b/gradle/validation/missing-docs-check.gradle
index e9cb6ae..781208a 100644
--- a/gradle/validation/missing-docs-check.gradle
+++ b/gradle/validation/missing-docs-check.gradle
@@ -89,7 +89,7 @@ class CheckMissingDocsTask extends DefaultTask {
   def checkMissingJavadocs(File dir, String level) {
     def output = new ByteArrayOutputStream()
     def result = project.exec {
-      executable project.externalToolExecutables["python3"]
+      executable project.externalTool("python3")
       ignoreExitValue = true
       standardOutput = output
       errorOutput = output


[lucene-solr] 01/39: LUCENE-9411: Fail complation on warnings, 9x gradle-only

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 0edf0f34f77c962efe5141e33c47fe3558a0e600
Author: Erick Erickson <Er...@gmail.com>
AuthorDate: Tue Jun 23 16:10:49 2020 -0400

    LUCENE-9411: Fail complation on warnings, 9x gradle-only
---
 build.gradle                                       |  3 +-
 gradle/defaults-java.gradle                        |  1 +
 gradle/hacks/findbugs.gradle                       | 45 ++++++++++++++++++++++
 gradle/validation/jar-checks.gradle                |  4 +-
 lucene/CHANGES.txt                                 |  3 ++
 .../solr/common/util/JsonSchemaValidator.java      | 11 ++----
 6 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/build.gradle b/build.gradle
index 83368a1..9c07bc7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -150,6 +150,7 @@ apply from: file('gradle/documentation/documentation.gradle')
 apply from: file('gradle/documentation/changes-to-html.gradle')
 apply from: file('gradle/documentation/markdown.gradle')
 apply from: file('gradle/render-javadoc.gradle')
+apply from: file('gradle/hacks/findbugs.gradle')
 
 allprojects {
   task ufclasspath {
@@ -166,4 +167,4 @@ allprojects {
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/gradle/defaults-java.gradle b/gradle/defaults-java.gradle
index 584054c..4d0fae7 100644
--- a/gradle/defaults-java.gradle
+++ b/gradle/defaults-java.gradle
@@ -33,6 +33,7 @@ allprojects {
         "-Xdoclint:-missing",
         "-Xdoclint:-accessibility",
         "-proc:none",  // proc:none was added because of LOG4J2-1925 / JDK-8186647
+        "-Werror",
       ]
     }
   }
diff --git a/gradle/hacks/findbugs.gradle b/gradle/hacks/findbugs.gradle
new file mode 100644
index 0000000..bdbdb7e
--- /dev/null
+++ b/gradle/hacks/findbugs.gradle
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */ 
+
+// See LUCENE-9411. This hack adds compile-time only dependencies
+// on findbugs annotations. Otherwise javac generates odd warnings about missing
+// type information.
+
+configure([project(":solr:core"),
+           project(":solr:solrj"),
+           project(":solr:contrib:prometheus-exporter")]) {
+  plugins.withType(JavaPlugin) {
+    dependencies {
+      // Use versionless variants because these libraries are in versions.lock.
+      compileOnly     'com.google.errorprone:error_prone_annotations'
+      testCompileOnly 'com.google.errorprone:error_prone_annotations'
+      compileOnly     'com.google.code.findbugs:jsr305'
+      testCompileOnly 'com.google.code.findbugs:jsr305'
+
+      // This one isn't.
+      compileOnly 'com.google.code.findbugs:annotations:3.0.1'
+      testCompileOnly 'com.google.code.findbugs:annotations:3.0.1'
+    }
+
+    // Exclude these from jar validation and license checks.
+    configurations.jarValidation {
+      exclude group: "com.google.code.findbugs", module: "jsr305"
+      exclude group: "com.google.code.findbugs", module: "annotations"
+      exclude group: "com.google.errorprone", module: "error_prone_annotations"
+    }
+  }
+}
diff --git a/gradle/validation/jar-checks.gradle b/gradle/validation/jar-checks.gradle
index b369b06..61db9a1 100644
--- a/gradle/validation/jar-checks.gradle
+++ b/gradle/validation/jar-checks.gradle
@@ -115,7 +115,9 @@ subprojects {
       ArrayDeque<ResolvedDependency> queue = new ArrayDeque<>()
       configurations.jarValidation.extendsFrom.each { conf ->
         if (excludeRules) {
-          conf = configurations.detachedConfiguration().extendsFrom(conf)
+          conf = conf.copyRecursive()
+          conf.canBeResolved = true
+          conf.canBeConsumed = true
           conf.excludeRules = excludeRules
         }
         if (conf.canBeResolved) {
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index a3c27ef..29d5aba 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -138,6 +138,9 @@ Other
 * LUCENE-9267: Update MatchingQueries documentation to correct
   time unit. (Pierre-Luc Perron via Mike Drob)
 
+* LUCENE-9411: Fail complation on warnings, 9x gradle-only (Erick Erickson, Dawid Weiss)
+  Deserves mention here as well as Lucene CHANGES.txt since it affects both.
+
 ======================= Lucene 8.6.0 =======================
 
 API Changes
diff --git a/solr/solrj/src/java/org/apache/solr/common/util/JsonSchemaValidator.java b/solr/solrj/src/java/org/apache/solr/common/util/JsonSchemaValidator.java
index 3231eb5..3e39525 100644
--- a/solr/solrj/src/java/org/apache/solr/common/util/JsonSchemaValidator.java
+++ b/solr/solrj/src/java/org/apache/solr/common/util/JsonSchemaValidator.java
@@ -34,21 +34,18 @@ import java.util.function.Function;
  * It validates most aspects of json schema but it is NOT A FULLY COMPLIANT JSON schema parser or validator.
  * This validator borrow some design's idea from https://github.com/networknt/json-schema-validator
  */
-@SuppressWarnings({"unchecked"})
+@SuppressWarnings({"unchecked", "rawtypes"})
 public class JsonSchemaValidator {
 
-  @SuppressWarnings({"unchecked", "rawtypes"})
   private List<Validator> validators;
   private static Set<String> KNOWN_FNAMES = new HashSet<>(Arrays.asList(
       "description","documentation","default","additionalProperties", "#include"));
 
 
-  @SuppressWarnings({"rawtypes"})
   public JsonSchemaValidator(String jsonString) {
     this((Map) Utils.fromJSONString(jsonString));
   }
 
-  @SuppressWarnings({"rawtypes"})
   public JsonSchemaValidator(Map jsonSchema) {
     this.validators = new LinkedList<>();
     for (Object fname : jsonSchema.keySet()) {
@@ -61,7 +58,6 @@ public class JsonSchemaValidator {
     }
   }
 
-  @SuppressWarnings({"rawtypes"})
   static final Map<String, Function<Pair<Map,Object>, Validator>> VALIDATORS = new HashMap<>();
 
   static {
@@ -79,7 +75,6 @@ public class JsonSchemaValidator {
     return errs.isEmpty() ? null : errs;
   }
 
-  @SuppressWarnings({"unchecked", "rawtypes"})
   boolean validate(Object data, List<String> errs) {
     if (data == null) return true;
     for (Validator validator : validators) {
@@ -93,7 +88,6 @@ public class JsonSchemaValidator {
 }
 
 abstract class Validator<T> {
-  @SuppressWarnings("unused")
   Validator(@SuppressWarnings({"rawtypes"})Map schema, T properties) {};
   abstract boolean validate(Object o, List<String> errs);
 }
@@ -182,7 +176,7 @@ class TypeValidator extends Validator<Object> {
 @SuppressWarnings({"rawtypes"})
 class ItemsValidator extends Validator<Map> {
   private JsonSchemaValidator validator;
-  ItemsValidator(@SuppressWarnings({"rawtypes"})Map schema, @SuppressWarnings({"rawtypes"})Map properties) {
+  ItemsValidator(Map schema, Map properties) {
     super(schema, properties);
     validator = new JsonSchemaValidator(properties);
   }
@@ -282,6 +276,7 @@ class PropertiesValidator extends Validator<Map<String, Map>> {
   }
 
   @Override
+  @SuppressWarnings({"rawtypes"})
   boolean validate(Object o, List<String> errs) {
     if (o instanceof Map) {
       @SuppressWarnings({"rawtypes"})


[lucene-solr] 24/39: LUCENE-9438: moved eclipse template files under corresponding gradle's script.

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 17770b3a2c72b56bbb1e106772f149268649d669
Author: Dawid Weiss <dw...@apache.org>
AuthorDate: Mon Aug 31 15:09:26 2020 +0200

    LUCENE-9438: moved eclipse template files under corresponding gradle's script.
---
 gradle/defaults.gradle                                              | 6 ++++++
 gradle/ide/eclipse.gradle                                           | 4 +++-
 {dev-tools => gradle/ide}/eclipse/dot.classpath.xsl                 | 0
 {dev-tools => gradle/ide}/eclipse/dot.project                       | 0
 .../ide}/eclipse/dot.settings/org.eclipse.core.resources.prefs      | 0
 .../ide}/eclipse/dot.settings/org.eclipse.jdt.core.prefs            | 0
 .../ide}/eclipse/dot.settings/org.eclipse.jdt.ui.prefs              | 0
 {dev-tools => gradle/ide}/eclipse/run-solr-cloud.launch             | 0
 {dev-tools => gradle/ide}/eclipse/run-solr.launch                   | 0
 {dev-tools => gradle/ide}/eclipse/run-test-cases.launch             | 0
 10 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/gradle/defaults.gradle b/gradle/defaults.gradle
index 5f11803..a011add 100644
--- a/gradle/defaults.gradle
+++ b/gradle/defaults.gradle
@@ -57,5 +57,11 @@ allprojects {
     propertyOrEnvOrDefault = { propName, envName, defValue ->
       return propertyOrDefault(propName, envOrDefault(envName, defValue));
     }
+
+    // Locate script-relative resource folder. This is context-sensitive so pass
+    // the right buildscript (top-level).
+    scriptResources = { buildscript ->
+      return file(buildscript.sourceFile.absolutePath.replaceAll('.gradle$', ""))
+    }
   }
 }
diff --git a/gradle/ide/eclipse.gradle b/gradle/ide/eclipse.gradle
index 3bebd1d..e414112 100644
--- a/gradle/ide/eclipse.gradle
+++ b/gradle/ide/eclipse.gradle
@@ -18,6 +18,8 @@
 import org.gradle.plugins.ide.eclipse.model.SourceFolder
 import org.gradle.plugins.ide.eclipse.model.ClasspathEntry
 
+def resources = scriptResources(buildscript)
+
 configure(rootProject) {
   apply plugin: "eclipse"
 
@@ -73,7 +75,7 @@ configure(rootProject) {
   eclipseJdt {
     doLast {
       project.sync {
-        from rootProject.file("dev-tools/eclipse/dot.settings")
+        from rootProject.file("${resources}/dot.settings")
         into rootProject.file(".settings")
       }
     }
diff --git a/dev-tools/eclipse/dot.classpath.xsl b/gradle/ide/eclipse/dot.classpath.xsl
similarity index 100%
rename from dev-tools/eclipse/dot.classpath.xsl
rename to gradle/ide/eclipse/dot.classpath.xsl
diff --git a/dev-tools/eclipse/dot.project b/gradle/ide/eclipse/dot.project
similarity index 100%
rename from dev-tools/eclipse/dot.project
rename to gradle/ide/eclipse/dot.project
diff --git a/dev-tools/eclipse/dot.settings/org.eclipse.core.resources.prefs b/gradle/ide/eclipse/dot.settings/org.eclipse.core.resources.prefs
similarity index 100%
rename from dev-tools/eclipse/dot.settings/org.eclipse.core.resources.prefs
rename to gradle/ide/eclipse/dot.settings/org.eclipse.core.resources.prefs
diff --git a/dev-tools/eclipse/dot.settings/org.eclipse.jdt.core.prefs b/gradle/ide/eclipse/dot.settings/org.eclipse.jdt.core.prefs
similarity index 100%
rename from dev-tools/eclipse/dot.settings/org.eclipse.jdt.core.prefs
rename to gradle/ide/eclipse/dot.settings/org.eclipse.jdt.core.prefs
diff --git a/dev-tools/eclipse/dot.settings/org.eclipse.jdt.ui.prefs b/gradle/ide/eclipse/dot.settings/org.eclipse.jdt.ui.prefs
similarity index 100%
rename from dev-tools/eclipse/dot.settings/org.eclipse.jdt.ui.prefs
rename to gradle/ide/eclipse/dot.settings/org.eclipse.jdt.ui.prefs
diff --git a/dev-tools/eclipse/run-solr-cloud.launch b/gradle/ide/eclipse/run-solr-cloud.launch
similarity index 100%
rename from dev-tools/eclipse/run-solr-cloud.launch
rename to gradle/ide/eclipse/run-solr-cloud.launch
diff --git a/dev-tools/eclipse/run-solr.launch b/gradle/ide/eclipse/run-solr.launch
similarity index 100%
rename from dev-tools/eclipse/run-solr.launch
rename to gradle/ide/eclipse/run-solr.launch
diff --git a/dev-tools/eclipse/run-test-cases.launch b/gradle/ide/eclipse/run-test-cases.launch
similarity index 100%
rename from dev-tools/eclipse/run-test-cases.launch
rename to gradle/ide/eclipse/run-test-cases.launch


[lucene-solr] 26/39: LUCENE-9492: Fix beasting to accept also task names in form ":project:beast"; fix bug with default value rejected by Integer.parseInt (#1808)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit a3665fe1e29df90168f70ca2d0402cf7999cd566
Author: Uwe Schindler <us...@apache.org>
AuthorDate: Mon Aug 31 18:09:21 2020 +0200

    LUCENE-9492: Fix beasting to accept also task names in form ":project:beast"; fix bug with default value rejected by Integer.parseInt (#1808)
---
 gradle/testing/beasting.gradle | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle/testing/beasting.gradle b/gradle/testing/beasting.gradle
index c4b5303..8934100 100644
--- a/gradle/testing/beasting.gradle
+++ b/gradle/testing/beasting.gradle
@@ -23,7 +23,7 @@
 //       runner duplicated suite names (much like https://github.com/gradle/test-retry-gradle-plugin)
 // TODO: this is a somewhat related issue: https://github.com/gradle/test-retry-gradle-plugin/issues/29
 
-def beastingMode = gradle.startParameter.taskNames.contains("beast");
+def beastingMode = gradle.startParameter.taskNames.any{ name -> name == 'beast' || name.endsWith(':beast') }
 
 allprojects {
   plugins.withType(JavaPlugin) {
@@ -47,7 +47,7 @@ if (beastingMode) {
         group "Verification"
       }
 
-      def dups = Integer.parseInt(resolvedTestOption("tests.dups"))
+      def dups = Integer.parseInt(resolvedTestOption("tests.dups") as String)
       if (dups <= 0) {
         throw new GradleException("Specify -Ptests.dups=[count] for beast task.")
       }


[lucene-solr] 03/39: LUCENE-9465: 'beast' task from within gradle (#1757)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 17d664ff89800015966dd4cdfb30b53321018610
Author: Dawid Weiss <dw...@apache.org>
AuthorDate: Tue Aug 18 09:28:50 2020 +0200

    LUCENE-9465: 'beast' task from within gradle (#1757)
---
 build.gradle                           |  1 +
 gradle/testing/beasting.gradle         | 82 ++++++++++++++++++++++++++++++++++
 gradle/testing/defaults-tests.gradle   |  3 +-
 gradle/testing/fail-on-no-tests.gradle |  2 +-
 gradle/testing/randomization.gradle    |  8 ++--
 help/tests.txt                         | 15 +++++++
 6 files changed, 106 insertions(+), 5 deletions(-)

diff --git a/build.gradle b/build.gradle
index 288a6a7..f5ad04a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -132,6 +132,7 @@ apply from: file('gradle/testing/per-project-summary.gradle')
 apply from: file('gradle/testing/slowest-tests-at-end.gradle')
 apply from: file('gradle/testing/failed-tests-at-end.gradle')
 apply from: file('gradle/testing/profiling.gradle')
+apply from: file('gradle/testing/beasting.gradle')
 apply from: file('gradle/help.gradle')
 
 // Ant-compatibility layer. ALL OF THESE SHOULD BE GONE at some point. They are
diff --git a/gradle/testing/beasting.gradle b/gradle/testing/beasting.gradle
new file mode 100644
index 0000000..1604cdb
--- /dev/null
+++ b/gradle/testing/beasting.gradle
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This adds 'beast' task which clones tests a given number of times (preferably
+// constrained with a filtering pattern passed via '--tests').
+
+// TODO: subtasks are not run in parallel (sigh, gradle removed this capability for intra-project tasks).
+// TODO: maybe it would be better to take a deeper approach and just feed the task
+//       runner duplicated suite names (much like https://github.com/gradle/test-retry-gradle-plugin)
+// TODO: this is a somewhat related issue: https://github.com/gradle/test-retry-gradle-plugin/issues/29
+
+def beastingMode = gradle.startParameter.taskNames.contains("beast");
+
+if (beastingMode) {
+  if (rootProject.rootSeedUserProvided) {
+    logger.warn("Root randomization seed is externally provided, all duplicated runs will use the same starting seed.")
+  }
+
+  allprojects {
+    plugins.withType(JavaPlugin) {
+      task beast(type: BeastTask) {
+        description "Run a test suite (or a set of tests) many times over (duplicate 'test' task)."
+        group "Verification"
+      }
+
+      def dups = Integer.parseInt(propertyOrDefault("tests.dups", "0"))
+      if (dups <= 0) {
+        throw new GradleException("Specify -Ptests.dups=[count] for beast task.")
+      }
+
+      // generate N test tasks and attach them to the beasting task for this project;
+      // the test filter will be applied by the beast task once it is received from
+      // command line.
+      def subtasks = (1..dups).collect { value ->
+        return tasks.create(name: "test_${value}", type: Test, {
+          failFast = true
+          doFirst {
+            // If there is a global root seed, use it (all duplicated tasks will run
+            // from the same starting seed). Otherwise pick a sequential derivative.
+            if (!rootProject.rootSeedUserProvided) {
+              systemProperty("tests.seed",
+                  String.format("%08X", new Random(rootProject.rootSeedLong + value).nextLong()))
+            }
+          }
+        })
+      }
+
+      beast.dependsOn subtasks
+    }
+  }
+}
+
+/**
+ * We have to declare a dummy task here to be able to reuse the same syntax for 'test' task
+ * filter option.
+ */
+class BeastTask extends DefaultTask {
+  @Option(option = "tests", description = "Sets test class or method name to be included, '*' is supported.")
+  public void setTestNamePatterns(List<String> patterns) {
+    taskDependencies.getDependencies(this).each { subtask ->
+      subtask.filter.setCommandLineIncludePatterns(patterns)
+    }
+  }
+
+  @TaskAction
+  void run() {
+  }
+}
\ No newline at end of file
diff --git a/gradle/testing/defaults-tests.gradle b/gradle/testing/defaults-tests.gradle
index e59c5c9..9bca17b 100644
--- a/gradle/testing/defaults-tests.gradle
+++ b/gradle/testing/defaults-tests.gradle
@@ -50,8 +50,9 @@ allprojects {
       }
     }
 
-    test {
+    tasks.withType(Test) {
       reports.junitXml.destination file(propertyOrDefault("reports.dest", "${reports.junitXml.destination.toString()}"))
+
       ext {
         testOutputsDir = file("${reports.junitXml.destination}/outputs")
       }
diff --git a/gradle/testing/fail-on-no-tests.gradle b/gradle/testing/fail-on-no-tests.gradle
index 4851b47..db763d8 100644
--- a/gradle/testing/fail-on-no-tests.gradle
+++ b/gradle/testing/fail-on-no-tests.gradle
@@ -19,7 +19,7 @@
 
 configure(allprojects) {
   plugins.withType(JavaPlugin) {
-    test {
+    tasks.withType(Test) {
       filter {
         failOnNoMatchingTests = false
       }
diff --git a/gradle/testing/randomization.gradle b/gradle/testing/randomization.gradle
index 0f36bae..f1d57d0 100644
--- a/gradle/testing/randomization.gradle
+++ b/gradle/testing/randomization.gradle
@@ -37,6 +37,7 @@ buildscript {
 configure(rootProject) {
   ext {
     rootSeed = propertyOrDefault('tests.seed', String.format("%08X", new Random().nextLong()))
+    rootSeedUserProvided = (propertyOrDefault('tests.seed', null) != null)
     rootSeedLong = SeedUtils.parseSeedChain(rootSeed)[0]
     projectSeedLong = rootSeedLong ^ project.path.hashCode()
   }
@@ -62,7 +63,7 @@ allprojects {
       testOptions = [
           // seed, repetition and amplification.
           [propName: 'tests.seed', value: "random", description: "Sets the master randomization seed."],
-          [propName: 'tests.iters', value: null, description: "Duplicate (re-run) each test N times."],
+          [propName: 'tests.iters', value: null, description: "Duplicate (re-run) each test case N times."],
           [propName: 'tests.multiplier', value: 1, description: "Value multiplier for randomized tests."],
           [propName: 'tests.maxfailures', value: null, description: "Skip tests after a given number of failures."],
           [propName: 'tests.timeoutSuite', value: null, description: "Timeout (in millis) for an entire suite."],
@@ -157,7 +158,7 @@ allprojects {
       }
 
       // Append resolved test properties to the test task.
-      test {
+      tasks.withType(Test) { task ->
         // TODO: we could remove opts with "buildOnly: true" (?)
         systemProperties testOptionsResolved
 
@@ -237,9 +238,10 @@ if (vmName =~ /(?i)(hotspot|openjdk|jrockit)/ &&
   logger.debug("Enabling HashMap assertions.")
   allprojects {
     plugins.withType(JavaPlugin) {
-      test {
+      tasks.withType(Test) { task ->  
         jvmArgs("-da:java.util.HashMap")
       }
     }
   }
 }
+
diff --git a/help/tests.txt b/help/tests.txt
index 30b1f4a..5054c0e 100644
--- a/help/tests.txt
+++ b/help/tests.txt
@@ -101,6 +101,21 @@ cleanTest task:
 
 gradlew -p lucene/core cleanTest test -Ptests.seed=deadbeef
 
+The 'tests.iters' option should be sufficient for individual test cases
+and is *much* faster than trying to duplicate re-runs of the entire
+test suites. When it is absolutely needed to re-run an entire suite (because
+of randomization in the static initialization, for example), you can do it
+by running the 'beast' task with 'tests.dups' option:
+
+gradlew -p lucene/core beast -Ptests.dups=10 --tests TestPerFieldDocValuesFormat
+
+Note the filter (--tests) used to narrow down test reiterations to a particular
+class. You can use any filter, including no filter at all, but it rarely makes
+sense (will take ages). By default the test tasks generated by the 'beast' mode
+use a random starting seed for randomization. If you pass an explicit seed, this
+won't be the case (all tasks will use exactly the same starting seed):
+
+gradlew -p lucene/core beast -Ptests.dups=10 --tests TestPerFieldDocValuesFormat -Dtests.seed=deadbeef
 
 Verbose mode and debugging
 --------------------------


[lucene-solr] 12/39: Move Solr-specific config.

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 691aa6de4d743d624c8c0c98eb6fdb62feef6f6d
Author: Dawid Weiss <dw...@apache.org>
AuthorDate: Mon Aug 31 15:43:56 2020 +0200

    Move Solr-specific config.
---
 build.gradle                                           | 4 ++--
 gradle/{ant-compat => solr}/solr-forbidden-apis.gradle | 0
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/build.gradle b/build.gradle
index 9050e7f..6d6ee2d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -166,7 +166,6 @@ apply from: file('gradle/ant-compat/misc.gradle')
 apply from: file('gradle/ant-compat/post-jar.gradle')
 apply from: file('gradle/ant-compat/test-classes-cross-deps.gradle')
 apply from: file('gradle/ant-compat/artifact-naming.gradle')
-apply from: file('gradle/ant-compat/solr-forbidden-apis.gradle')
 
 apply from: file('gradle/documentation/documentation.gradle')
 apply from: file('gradle/documentation/changes-to-html.gradle')
@@ -177,4 +176,5 @@ apply from: file('gradle/hacks/findbugs.gradle')
 apply from: file('gradle/hacks/gradle.gradle')
 apply from: file('gradle/hacks/hashmapAssertions.gradle')
 
-apply from: file('gradle/solr/packaging.gradle')
\ No newline at end of file
+apply from: file('gradle/solr/packaging.gradle')
+apply from: file('gradle/solr/solr-forbidden-apis.gradle')
diff --git a/gradle/ant-compat/solr-forbidden-apis.gradle b/gradle/solr/solr-forbidden-apis.gradle
similarity index 100%
rename from gradle/ant-compat/solr-forbidden-apis.gradle
rename to gradle/solr/solr-forbidden-apis.gradle


[lucene-solr] 11/39: LUCENE-9435: revert Solr's packaging stuff for now.

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 015e92f9e724eb60020c9a32be1f729f1f0f0ba1
Author: Dawid Weiss <dw...@apache.org>
AuthorDate: Mon Aug 31 14:55:45 2020 +0200

    LUCENE-9435: revert Solr's packaging stuff for now.
---
 build.gradle                                  |   2 +
 gradle/solr/packaging.gradle                  | 200 ++++++++++++++++++++++++++
 solr/contrib/prometheus-exporter/build.gradle |   8 ++
 3 files changed, 210 insertions(+)

diff --git a/build.gradle b/build.gradle
index bbdc7bc..9050e7f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -176,3 +176,5 @@ apply from: file('gradle/documentation/render-javadoc.gradle')
 apply from: file('gradle/hacks/findbugs.gradle')
 apply from: file('gradle/hacks/gradle.gradle')
 apply from: file('gradle/hacks/hashmapAssertions.gradle')
+
+apply from: file('gradle/solr/packaging.gradle')
\ No newline at end of file
diff --git a/gradle/solr/packaging.gradle b/gradle/solr/packaging.gradle
new file mode 100644
index 0000000..3b1ea92
--- /dev/null
+++ b/gradle/solr/packaging.gradle
@@ -0,0 +1,200 @@
+/*
+ * 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.
+ */
+
+
+// For Solr, a 'resolve' task is much more complex. There are three folders:
+// lib/
+// test-lib/
+// lucene-libs/
+//
+// There doesn't seem to be one ideal set of rules on how these should be created, but
+// I tried to imitate the current (master) logic present in ivy and ant files in this way:
+//
+// The "solr platform" set of dependencies is a union of all deps for (core, solrj, server).
+//
+// Then:
+// lib - these are module's "own" dependencies, excluding Lucene's that are not present in the
+//       solr platform.
+// lucene-libs - these are lucene modules declared as module's dependencies and not
+//       present in solr platform.
+// test-lib/ - libs not present in solr platform and not included in solr:test-framework.
+//
+// None of these are really needed with gradle... they should be collected just in the distribution
+// package, not at each project's level.
+//
+// Unfortunately this "resolution" process is also related to how the final Solr packaging is assembled.
+// I don't know how to untie these two cleanly.
+//
+
+configure(allprojects.findAll {project -> project.path.startsWith(":solr:contrib") }) {
+  plugins.withType(JavaPlugin) {
+    ext {
+      packagingDir = file("${buildDir}/packaging")
+      deps = file("${packagingDir}/${project.name}")
+    }
+
+    configurations {
+      solrPlatformLibs
+      solrTestPlatformLibs
+      runtimeLibs {
+        extendsFrom runtimeElements
+      }
+      packaging
+    }
+
+    dependencies {
+      solrPlatformLibs project(":solr:core")
+      solrPlatformLibs project(":solr:solrj")
+      solrPlatformLibs project(":solr:server")
+
+      solrTestPlatformLibs project(":solr:test-framework")
+    }
+
+    // An aggregate that configures lib, lucene-libs and test-lib in a temporary location.
+    task assemblePackaging(type: Sync) {
+      from "README.txt"
+
+      from ({
+        def externalLibs = configurations.runtimeLibs.copyRecursive { dep ->
+          if (dep instanceof org.gradle.api.artifacts.ProjectDependency) {
+            return !dep.dependencyProject.path.startsWith(":solr")
+          } else {
+            return true
+          }
+        }
+        return externalLibs - configurations.solrPlatformLibs
+      }, {
+        exclude "lucene-*"
+        into "lib"
+      })
+
+      from ({
+        def projectLibs = configurations.runtimeLibs.copyRecursive { dep ->
+          (dep instanceof org.gradle.api.artifacts.ProjectDependency)
+        }
+        return projectLibs - configurations.solrPlatformLibs
+      }, {
+        include "lucene-*"
+        into "lucene-libs"
+      })
+
+      into deps
+    }
+
+    task syncLib(type: Sync) {
+      dependsOn assemblePackaging
+
+      from(file("${deps}/lib"), {
+        include "**"
+      })
+      into file("${projectDir}/lib")
+    }
+
+    task syncTestLib(type: Sync) {
+      // From test runtime classpath exclude:
+      // 1) project dependencies (and their dependencies)
+      // 2) runtime dependencies
+      // What remains is this module's "own" test dependency.
+      from({
+        def testRuntimeLibs = configurations.testRuntimeClasspath.copyRecursive { dep ->
+          !(dep instanceof org.gradle.api.artifacts.ProjectDependency)
+        }
+
+        return testRuntimeLibs - configurations.runtimeLibs - configurations.solrTestPlatformLibs
+      })
+
+      into file("${projectDir}/test-lib")
+    }
+
+    task resolve() {
+      dependsOn syncLib, syncTestLib
+    }
+
+    // Contrib packaging currently depends on internal resolve.
+    artifacts {
+      packaging packagingDir, {
+        builtBy assemblePackaging
+      }
+    }
+  }
+}
+
+configure(project(":solr:example")) {
+  evaluationDependsOn(":solr:example") // explicitly wait for other configs to be applied
+
+  task resolve(type: Copy) {
+    from(configurations.postJar, {
+      into "exampledocs/"
+    })
+
+    into projectDir
+  }
+}
+
+configure(project(":solr:server")) {
+  evaluationDependsOn(":solr:server")
+
+  task resolve(type: Copy) {
+    dependsOn assemblePackaging
+
+    from({ packagingDir }, {
+      include "**/*.jar"
+      include "solr-webapp/webapp/**"
+      includeEmptyDirs false
+    })
+
+    into projectDir
+  }
+}
+
+configure(project(":solr:core")) {
+  evaluationDependsOn(":solr:core")
+
+  configurations {
+    runtimeLibs {
+      extendsFrom runtimeElements
+    }
+  }
+
+  task resolve(type: Sync) {
+    from({
+      def ownDeps = configurations.runtimeLibs.copyRecursive { dep ->
+        if (dep instanceof org.gradle.api.artifacts.ProjectDependency) {
+          return !dep.dependencyProject.path.startsWith(":solr")
+        } else {
+          return true
+        }
+      }
+      return ownDeps
+    }, {
+      exclude "lucene-*"
+    })
+
+    into "lib"
+  }
+}
+
+configure(project(":solr:solrj")) {
+  evaluationDependsOn(":solr:solrj")
+
+  task resolve(type: Sync) {
+    from({ configurations.runtimeClasspath }, {
+    })
+
+    into "lib"
+  }
+}
diff --git a/solr/contrib/prometheus-exporter/build.gradle b/solr/contrib/prometheus-exporter/build.gradle
index 6ff390f..13a9748 100644
--- a/solr/contrib/prometheus-exporter/build.gradle
+++ b/solr/contrib/prometheus-exporter/build.gradle
@@ -37,3 +37,11 @@ dependencies {
 
   testImplementation project(':solr:test-framework')
 }
+
+// Add two folders to default packaging.
+assemblePackaging {
+  from(projectDir, {
+    include "bin/**"
+    include "conf/**"
+  })
+}
\ No newline at end of file


[lucene-solr] 13/39: LUCENE-9215: replace checkJavaDocs.py with doclet (#1802)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 7f54fa2279603e7fe15b52cae28cbaf04ff30322
Author: Robert Muir <rm...@apache.org>
AuthorDate: Wed Sep 2 08:29:17 2020 -0400

    LUCENE-9215: replace checkJavaDocs.py with doclet (#1802)
    
    This has the same logic as the previous python, but no longer relies
    upon parsing HTML output, instead using java's doclet processor.
    
    The errors are reported like "normal" javadoc errors with source file
    name and line number and happen when running "gradlew javadoc"
    
    Although the "rules" are the same as the previous python, the python had
    some bugs where the checker didn't quite do exactly what we wanted, so
    some fixes were applied throughout.
    
    Co-authored-by: Dawid Weiss <da...@carrotsearch.com>
    Co-authored-by: Uwe Schindler <us...@apache.org>
---
 build.gradle                                       |   1 -
 {solr => dev-tools/missing-doclet}/build.gradle    |   8 +-
 .../missing-doclet/settings.gradle                 |   5 -
 .../apache/lucene/missingdoclet/MissingDoclet.java | 435 +++++++++++++++++++++
 dev-tools/scripts/checkJavaDocs.py                 | 392 -------------------
 dev-tools/scripts/smokeTestRelease.py              |  34 +-
 gradle/documentation/render-javadoc.gradle         | 263 +++++++++++++
 gradle/validation/validate-source-patterns.gradle  |  37 +-
 lucene/analysis/common/build.gradle                |   1 -
 .../analysis/compound/hyphenation/TernaryTree.java |   4 +
 lucene/analysis/nori/build.gradle                  |   1 +
 .../java/org/apache/lucene/codecs/Placeholder.java |   3 +-
 lucene/benchmark/build.gradle                      |   2 +-
 .../CachingNaiveBayesClassifier.java               |   1 +
 .../sharedterms/STUniformSplitTermsWriter.java     |   2 +-
 .../lucene/search/MultiCollectorManager.java       |   5 +
 .../lucene/search/similarities/AxiomaticF1EXP.java |   2 +-
 .../lucene/search/similarities/AxiomaticF1LOG.java |   2 +-
 .../lucene/search/similarities/AxiomaticF2EXP.java |   2 +-
 .../lucene/search/similarities/AxiomaticF2LOG.java |   2 +-
 .../lucene/search/similarities/AxiomaticF3EXP.java |   2 +-
 .../lucene/search/similarities/AxiomaticF3LOG.java |   2 +-
 .../lucene/search/spans/SpanContainingQuery.java   |   6 +-
 .../apache/lucene/search/spans/SpanNearQuery.java  |   4 +
 .../apache/lucene/search/spans/SpanNotQuery.java   |   4 +
 .../apache/lucene/search/spans/SpanOrQuery.java    |   4 +
 .../search/spans/SpanPositionCheckQuery.java       |   4 +
 .../apache/lucene/search/spans/SpanTermQuery.java  |   4 +
 .../lucene/search/spans/SpanWithinQuery.java       |   6 +-
 .../java/org/apache/lucene/util/PagedBytes.java    |   8 +
 lucene/grouping/build.gradle                       |   2 +-
 .../apache/lucene/index/memory/MemoryIndex.java    |   1 +
 lucene/misc/build.gradle                           |   2 +-
 .../org/apache/lucene/document/LazyDocument.java   |   1 +
 lucene/queries/build.gradle                        |   3 +-
 .../lucene/queries/function/FunctionQuery.java     |   8 +
 .../function/valuesource/MultiFunction.java        |   1 +
 lucene/queryparser/build.gradle                    |   2 +
 .../precedence/processors/package-info.java        |  39 ++
 .../flexible/precedence/processors/package.html    |  47 ---
 lucene/replicator/build.gradle                     |   1 +
 lucene/spatial-extras/build.gradle                 |   2 +
 .../org/apache/lucene/spatial/package-info.java    |   7 +-
 .../java/org/apache/lucene/spatial/package.html    |  26 --
 .../lucene/spatial/prefix/PrefixTreeStrategy.java  |   1 +
 .../lucene/spatial/prefix/tree/QuadPrefixTree.java |   1 +
 .../apache/lucene/spatial/util/package-info.java   |   7 +-
 .../org/apache/lucene/spatial/util/package.html    |  26 --
 .../index/BaseTermVectorsFormatTestCase.java       |   2 +
 .../apache/lucene/index/PointsStackTracker.java    |   1 +
 .../lucene/search/ShardSearchingTestBase.java      |   1 +
 settings.gradle                                    |   1 +
 solr/build.gradle                                  |   4 +-
 solr/contrib/analysis-extras/build.gradle          |   1 -
 .../java/org/apache/solr/query/package-info.java}  |   9 +-
 .../src/java/org/apache/solr/query/package.html    |  27 --
 .../apache/solr/request/json/package-info.java}    |   9 +-
 .../java/org/apache/solr/request/json/package.html |  27 --
 .../apache/solr/request/macro/package-info.java}   |   9 +-
 .../org/apache/solr/request/macro/package.html     |  27 --
 .../apache/solr/search/facet/package-info.java}    |  10 +-
 .../java/org/apache/solr/search/facet/package.html |  28 --
 .../solr/util/circuitbreaker/package-info.java}    |   9 +-
 solr/test-framework/build.gradle                   |   1 +
 64 files changed, 896 insertions(+), 693 deletions(-)

diff --git a/build.gradle b/build.gradle
index 6d6ee2d..d20deeb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -138,7 +138,6 @@ apply from: file('gradle/validation/rat-sources.gradle')
 apply from: file('gradle/validation/owasp-dependency-check.gradle')
 apply from: file('gradle/validation/ecj-lint.gradle')
 apply from: file('gradle/validation/gradlew-scripts-tweaked.gradle')
-apply from: file('gradle/validation/missing-docs-check.gradle')
 apply from: file('gradle/validation/validate-log-calls.gradle')
 apply from: file('gradle/validation/check-broken-links.gradle')
 
diff --git a/solr/build.gradle b/dev-tools/missing-doclet/build.gradle
similarity index 85%
copy from solr/build.gradle
copy to dev-tools/missing-doclet/build.gradle
index 9edc4d1..4e680b6 100644
--- a/solr/build.gradle
+++ b/dev-tools/missing-doclet/build.gradle
@@ -15,8 +15,8 @@
  * limitations under the License.
  */
 
-description = 'Parent project for Apache Solr'
+apply plugin: 'java-library'
 
-subprojects {
-  group "org.apache.solr"
-}
\ No newline at end of file
+version = "1.0.0-SNAPSHOT"
+group = "org.apache.lucene.tools"
+description = 'Doclet-based javadoc validation.'
diff --git a/solr/build.gradle b/dev-tools/missing-doclet/settings.gradle
similarity index 90%
copy from solr/build.gradle
copy to dev-tools/missing-doclet/settings.gradle
index 9edc4d1..6a9c064 100644
--- a/solr/build.gradle
+++ b/dev-tools/missing-doclet/settings.gradle
@@ -15,8 +15,3 @@
  * limitations under the License.
  */
 
-description = 'Parent project for Apache Solr'
-
-subprojects {
-  group "org.apache.solr"
-}
\ No newline at end of file
diff --git a/dev-tools/missing-doclet/src/main/java/org/apache/lucene/missingdoclet/MissingDoclet.java b/dev-tools/missing-doclet/src/main/java/org/apache/lucene/missingdoclet/MissingDoclet.java
new file mode 100644
index 0000000..89c205f
--- /dev/null
+++ b/dev-tools/missing-doclet/src/main/java/org/apache/lucene/missingdoclet/MissingDoclet.java
@@ -0,0 +1,435 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.missingdoclet;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.tools.Diagnostic;
+
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.doctree.ParamTree;
+import com.sun.source.util.DocTrees;
+
+import jdk.javadoc.doclet.Doclet;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+import jdk.javadoc.doclet.StandardDoclet;
+
+/**
+ * Checks for missing javadocs, where missing also means "only whitespace" or "license header".
+ * Has option --missing-level (package, class, method, parameter) so that we can improve over time.
+ * Has option --missing-ignore to ignore individual elements (such as split packages). 
+ *   It isn't recursive, just ignores exactly the elements you tell it.
+ *   This should be removed when packaging is fixed to no longer be split across JARs.
+ * Has option --missing-method to apply "method" level to selected packages (fix one at a time).
+ *   Matches package names exactly: so you'll need to list subpackages separately.
+ */
+public class MissingDoclet extends StandardDoclet {
+  // checks that modules and packages have documentation
+  private static final int PACKAGE = 0;
+  // + checks that classes, interfaces, enums, and annotation types have documentation
+  private static final int CLASS = 1;
+  // + checks that methods, constructors, fields, and enumerated constants have documentation
+  private static final int METHOD = 2;
+  // + checks that @param tags are present for any method/constructor parameters
+  private static final int PARAMETER = 3;
+  int level = PARAMETER;
+  Reporter reporter;
+  DocletEnvironment docEnv;
+  DocTrees docTrees;
+  Elements elementUtils;
+  Set<String> ignored = Collections.emptySet();
+  Set<String> methodPackages = Collections.emptySet();
+  
+  @Override
+  public Set<Doclet.Option> getSupportedOptions() {
+    Set<Doclet.Option> options = new HashSet<>();
+    options.addAll(super.getSupportedOptions());
+    options.add(new Doclet.Option() {
+      @Override
+      public int getArgumentCount() {
+        return 1;
+      }
+
+      @Override
+      public String getDescription() {
+        return "level to enforce for missing javadocs: [package, class, method, parameter]";
+      }
+
+      @Override
+      public Kind getKind() {
+        return Option.Kind.STANDARD;
+      }
+
+      @Override
+      public List<String> getNames() {
+        return Collections.singletonList("--missing-level");
+      }
+
+      @Override
+      public String getParameters() {
+        return "level";
+      }
+
+      @Override
+      public boolean process(String option, List<String> arguments) {
+        switch (arguments.get(0)) {
+          case "package":
+            level = PACKAGE;
+            return true;
+          case "class":
+            level = CLASS;
+            return true;
+          case "method":
+            level = METHOD;
+            return true;
+          case "parameter":
+            level = PARAMETER;
+            return true;
+          default:
+            return false;
+        }
+      }
+    });
+    options.add(new Doclet.Option() {
+      @Override
+      public int getArgumentCount() {
+        return 1;
+      }
+
+      @Override
+      public String getDescription() {
+        return "comma separated list of element names to ignore (e.g. as a workaround for split packages)";
+      }
+
+      @Override
+      public Kind getKind() {
+        return Option.Kind.STANDARD;
+      }
+
+      @Override
+      public List<String> getNames() {
+        return Collections.singletonList("--missing-ignore");
+      }
+
+      @Override
+      public String getParameters() {
+        return "ignoredNames";
+      }
+
+      @Override
+      public boolean process(String option, List<String> arguments) {
+        ignored = new HashSet<>(Arrays.asList(arguments.get(0).split(",")));
+        return true;
+      }
+    });
+    options.add(new Doclet.Option() {
+      @Override
+      public int getArgumentCount() {
+        return 1;
+      }
+
+      @Override
+      public String getDescription() {
+        return "comma separated list of packages to check at 'method' level";
+      }
+
+      @Override
+      public Kind getKind() {
+        return Option.Kind.STANDARD;
+      }
+
+      @Override
+      public List<String> getNames() {
+        return Collections.singletonList("--missing-method");
+      }
+
+      @Override
+      public String getParameters() {
+        return "packages";
+      }
+
+      @Override
+      public boolean process(String option, List<String> arguments) {
+        methodPackages = new HashSet<>(Arrays.asList(arguments.get(0).split(",")));
+        return true;
+      }
+    });
+    return options;
+  }
+
+  @Override
+  public void init(Locale locale, Reporter reporter) {
+    this.reporter = reporter;
+    super.init(locale, reporter);
+  }
+
+  @Override
+  public boolean run(DocletEnvironment docEnv) {
+    this.docEnv = docEnv;
+    this.docTrees = docEnv.getDocTrees();
+    this.elementUtils = docEnv.getElementUtils();
+    for (var element : docEnv.getIncludedElements()) {
+      check(element);
+    }
+
+    return super.run(docEnv);
+  }
+  
+  /**
+   * Returns effective check level for this element
+   */
+  private int level(Element element) {
+    String pkg = elementUtils.getPackageOf(element).getQualifiedName().toString();
+    if (methodPackages.contains(pkg)) {
+      return METHOD;
+    } else {
+      return level;
+    }
+  }
+  
+  /** 
+   * Check an individual element.
+   * This checks packages and types from the doctrees.
+   * It will recursively check methods/fields from encountered types when the level is "method"
+   */
+  private void check(Element element) {
+    switch(element.getKind()) {
+      case MODULE:
+        // don't check the unnamed module, it won't have javadocs
+        if (!((ModuleElement)element).isUnnamed()) {
+          checkComment(element);
+        }
+        break;
+      case PACKAGE:
+        checkComment(element);
+        break;
+      // class-like elements, check them, then recursively check their children (fields and methods)
+      case CLASS:
+      case INTERFACE:
+      case ENUM:
+      case ANNOTATION_TYPE:
+        if (level(element) >= CLASS) {
+          checkComment(element);
+          for (var subElement : element.getEnclosedElements()) {
+            // don't recurse into enclosed types, otherwise we'll double-check since they are already in the included docTree
+            if (subElement.getKind() == ElementKind.METHOD || 
+                subElement.getKind() == ElementKind.CONSTRUCTOR || 
+                subElement.getKind() == ElementKind.FIELD || 
+                subElement.getKind() == ElementKind.ENUM_CONSTANT) {
+              check(subElement);
+            }
+          }
+        }
+        break;
+      // method-like elements, check them if we are configured to do so
+      case METHOD:
+      case CONSTRUCTOR:
+      case FIELD:
+      case ENUM_CONSTANT:
+        if (level(element) >= METHOD && !isSyntheticEnumMethod(element)) {
+          checkComment(element);
+        }
+        break;
+      default:
+        error(element, "I don't know how to analyze " + element.getKind() + " yet.");
+    }
+  }
+
+  /**
+   * Return true if the method is synthetic enum method (values/valueOf).
+   * According to the doctree documentation, the "included" set never includes synthetic elements.
+   * UweSays: It should not happen but it happens!
+   */
+  private boolean isSyntheticEnumMethod(Element element) {
+    String simpleName = element.getSimpleName().toString();
+    if (simpleName.equals("values") || simpleName.equals("valueOf")) {
+      if (element.getEnclosingElement().getKind() == ElementKind.ENUM) {
+        return true;
+      }
+    }
+    return false;
+  }
+  
+  /**
+   * Checks that an element doesn't have missing javadocs.
+   * In addition to truly "missing", check that comments aren't solely whitespace (generated by some IDEs),
+   * that they aren't a license header masquerading as a javadoc comment.
+   */
+  private void checkComment(Element element) {
+    // sanity check that the element is really "included", because we do some recursion into types
+    if (!docEnv.isIncluded(element)) {
+      return;
+    }
+    // check that this element isn't on our ignore list. This is only used as a workaround for "split packages".
+    // ignoring a package isn't recursive (on purpose), we still check all the classes, etc. inside it.
+    // we just need to cope with the fact package-info.java isn't there because it is split across multiple jars.
+    if (ignored.contains(element.toString())) {
+      return;
+    }
+    var tree = docTrees.getDocCommentTree(element);
+    if (tree == null || tree.getFirstSentence().isEmpty()) {
+      // Check for methods that override other stuff and perhaps inherit their Javadocs.
+      if (hasInheritedJavadocs(element)) {
+        return;
+      } else {
+        error(element, "javadocs are missing");
+      }
+    } else {
+      var normalized = tree.getFirstSentence().get(0).toString()
+                       .replace('\u00A0', ' ')
+                       .trim()
+                       .toLowerCase(Locale.ROOT);
+      if (normalized.isEmpty()) {
+        error(element, "blank javadoc comment");
+      } else if (normalized.startsWith("licensed to the apache software foundation") ||
+                 normalized.startsWith("copyright 2004 the apache software foundation")) {
+        error(element, "comment is really a license");
+      }
+    }
+    if (level >= PARAMETER) {
+      checkParameters(element, tree);
+    }
+  }
+
+  private boolean hasInheritedJavadocs(Element element) {
+    boolean hasOverrides = element.getAnnotationMirrors().stream()
+        .anyMatch(ann -> ann.getAnnotationType().toString().equals(Override.class.getName()));
+
+    if (hasOverrides) {
+      // If an element has explicit @Overrides annotation, assume it does
+      // have inherited javadocs somewhere.
+      reporter.print(Diagnostic.Kind.NOTE, element, "javadoc empty but @Override declared, skipping.");
+      return true;
+    }
+
+    // Check for methods up the types tree.
+    if (element instanceof ExecutableElement) {
+      ExecutableElement thisMethod = (ExecutableElement) element;
+      Iterable<Element> superTypes =
+          () -> superTypeForInheritDoc(thisMethod.getEnclosingElement()).iterator();
+
+      for (Element sup : superTypes) {
+        for (ExecutableElement supMethod : ElementFilter.methodsIn(sup.getEnclosedElements())) {
+          TypeElement clazz = (TypeElement) thisMethod.getEnclosingElement();
+          if (elementUtils.overrides(thisMethod, supMethod, clazz)) {
+            // We could check supMethod for non-empty javadoc here. Don't know if this makes
+            // sense though as all methods will be verified in the end so it'd fail on the
+            // top of the hierarchy (if empty) anyway.
+            reporter.print(Diagnostic.Kind.NOTE, element, "javadoc empty but method overrides another, skipping.");
+            return true;
+          }
+        }
+      }
+    }
+
+    return false;
+  }
+
+
+  /* Find types from which methods in type may inherit javadoc, in the proper order.*/
+  private Stream<Element> superTypeForInheritDoc(Element type) {
+    TypeElement clazz = (TypeElement) type;
+    List<Element> interfaces = clazz.getInterfaces()
+        .stream()
+        .filter(tm -> tm.getKind() == TypeKind.DECLARED)
+        .map(tm -> ((DeclaredType) tm).asElement())
+        .collect(Collectors.toList());
+
+    Stream<Element> result = interfaces.stream();
+    result = Stream.concat(result, interfaces.stream().flatMap(this::superTypeForInheritDoc));
+
+    if (clazz.getSuperclass().getKind() == TypeKind.DECLARED) {
+      Element superClass = ((DeclaredType) clazz.getSuperclass()).asElement();
+      result = Stream.concat(result, Stream.of(superClass));
+      result = Stream.concat(result, superTypeForInheritDoc(superClass));
+    }
+
+    return result;
+  }
+
+  /** Checks there is a corresponding "param" tag for each method parameter */
+  private void checkParameters(Element element, DocCommentTree tree) {
+    if (element instanceof ExecutableElement) {
+      // record each @param that we see
+      Set<String> seenParameters = new HashSet<>();
+      if (tree != null) {
+        for (var tag : tree.getBlockTags()) {
+          if (tag instanceof ParamTree) {
+            var name = ((ParamTree)tag).getName().getName().toString();
+            seenParameters.add(name);
+          }
+        }
+      }
+      // now compare the method's formal parameter list against it
+      for (var param : ((ExecutableElement)element).getParameters()) {
+        var name = param.getSimpleName().toString();
+        if (!seenParameters.contains(name)) {
+          error(element, "missing javadoc @param for parameter '" + name + "'");
+        }
+      }
+    }
+  }
+  
+  /** logs a new error for the particular element */
+  private void error(Element element, String message) {
+    var fullMessage = new StringBuilder();
+    switch(element.getKind()) {
+      case MODULE:
+      case PACKAGE:
+        // for modules/packages, we don't have filename + line number, fully qualify
+        fullMessage.append(element.toString());
+        break;
+      case METHOD:
+      case CONSTRUCTOR:
+      case FIELD:
+      case ENUM_CONSTANT:
+        // for method-like elements, include the enclosing type to make it easier
+        fullMessage.append(element.getEnclosingElement().getSimpleName());
+        fullMessage.append(".");
+        fullMessage.append(element.getSimpleName());
+        break;
+      default:
+        // for anything else, use a simple name
+        fullMessage.append(element.getSimpleName());
+        break;
+    }
+    fullMessage.append(" (");
+    fullMessage.append(element.getKind().toString().toLowerCase(Locale.ROOT));
+    fullMessage.append("): ");
+    fullMessage.append(message);
+    reporter.print(Diagnostic.Kind.ERROR, element, fullMessage.toString());
+  }
+}
diff --git a/dev-tools/scripts/checkJavaDocs.py b/dev-tools/scripts/checkJavaDocs.py
deleted file mode 100644
index 14ded3d..0000000
--- a/dev-tools/scripts/checkJavaDocs.py
+++ /dev/null
@@ -1,392 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-import os
-import re
-
-reHREF = re.compile('<a.*?>(.*?)</a>', re.IGNORECASE)
-
-reMarkup = re.compile('<.*?>')
-reDivBlock = re.compile('<div class="block">(.*?)</div>', re.IGNORECASE)
-reCaption = re.compile('<caption><span>(.*?)</span>', re.IGNORECASE)
-reJ8Caption = re.compile('<h[23]>(.*?) Summary</h[23]>')
-reTDLastNested = re.compile('^<td class="colLast"><code><strong><a href="[^>]*\.([^>]*?)\.html" title="class in[^>]*">', re.IGNORECASE)
-reMethod = re.compile('^<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="[^>]*#([^>]*?)">', re.IGNORECASE)
-reColOne = re.compile('^<td class="colOne"><code><strong><a href="[^>]*#([^>]*?)">', re.IGNORECASE)
-reMemberNameLink = re.compile('^<td class="colLast"><code><span class="memberNameLink"><a href="[^>]*#([^>]*?)"', re.IGNORECASE)
-reNestedClassMemberNameLink = re.compile('^<td class="colLast"><code><span class="memberNameLink"><a href="[^>]*?".*?>(.*?)</a>', re.IGNORECASE)
-reMemberNameOneLink = re.compile('^<td class="colOne"><code><span class="memberNameLink"><a href="[^>]*#([^>]*?)"', re.IGNORECASE)
-
-# the Method detail section at the end
-reMethodDetail = re.compile('^<h[23]>Method Details?</h[23]>$', re.IGNORECASE)
-reMethodDetailAnchor = re.compile('^(?:</a>)?<a id="([^>]*?)">$', re.IGNORECASE)
-reJ13MethodDetailAnchor = re.compile('^(?:<h3>|</a>)<a id="([^>]*?)">[^>]*</a></h3>$', re.IGNORECASE)
-
-reTag = re.compile("(?i)<(\/?\w+)((\s+\w+(\s*=\s*(?:\".*?\"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>")
-
-def verifyHTML(s):
-
-  stack = []
-  upto = 0
-  while True:
-    m = reTag.search(s, upto)
-    if m is None:
-      break
-    tag = m.group(1)
-    upto = m.end(0)
-
-    if tag[:1] == '/':
-      justTag = tag[1:]
-    else:
-      justTag = tag
-      
-    if justTag.lower() in ('br', 'li', 'p', 'col'):
-      continue
-
-    if tag[:1] == '/':
-      if len(stack) == 0:
-        raise RuntimeError('saw closing "%s" without opening <%s...>' % (m.group(0), tag[1:]))
-      elif stack[-1][0] != tag[1:].lower():
-        raise RuntimeError('closing "%s" does not match opening "%s"' % (m.group(0), stack[-1][1]))
-      stack.pop()
-    else:
-      stack.append((tag.lower(), m.group(0)))
-
-  if len(stack) != 0:
-    raise RuntimeError('"%s" was never closed' % stack[-1][1])
-
-def cleanHTML(s):
-  s = reMarkup.sub('', s)
-  s = s.replace('&nbsp;', ' ')
-  s = s.replace('&lt;', '<')
-  s = s.replace('&gt;', '>')
-  s = s.replace('&amp;', '&')
-  return s.strip()
-
-reH3 = re.compile('^<h3>(.*?)</h3>', re.IGNORECASE | re.MULTILINE)
-reH4 = re.compile('^<h4>(.*?)</h4>', re.IGNORECASE | re.MULTILINE)
-reDetailsDiv = re.compile('<div class="details">')
-reEndOfClassData = re.compile('<!--.*END OF CLASS DATA.*-->')
-reBlockList = re.compile('<ul class="blockList(?:Last)?">')
-reCloseUl = re.compile('</ul>')
-
-def checkClassDetails(fullPath):
-  """
-  Checks for invalid HTML in the full javadocs under each field/method.
-  """
-
-  # TODO: only works with java7 generated javadocs now!
-  with open(fullPath, encoding='UTF-8') as f:
-    desc = []
-    cat = None
-    item = None
-    errors = []
-    inDetailsDiv = False
-    blockListDepth = 0
-    for line in f.readlines():
-      # Skip content up until  <div class="details">
-      if not inDetailsDiv:
-        if reDetailsDiv.match(line) is not None:
-          inDetailsDiv = True
-        continue
-
-      # Stop looking at content at closing details </div>, which is just before <!-- === END OF CLASS DATA === -->
-      if reEndOfClassData.match(line) is not None:
-        if len(desc) != 0:
-          try:
-            verifyHTML(''.join(desc))
-          except RuntimeError as re:
-            #print('    FAILED: %s' % re)
-            errors.append((cat, item, str(re)))
-        break
-
-      # <ul class="blockList(Last)"> is the boundary between items
-      if reBlockList.match(line) is not None:
-        blockListDepth += 1
-        if len(desc) != 0:
-          try:
-            verifyHTML(''.join(desc))
-          except RuntimeError as re:
-            #print('    FAILED: %s' % re)
-            errors.append((cat, item, str(re)))
-          del desc[:]
-
-      if blockListDepth == 3:
-        desc.append(line)
-
-      if reCloseUl.match(line) is not None:
-        blockListDepth -= 1
-      else:
-        m = reH3.search(line)
-        if m is not None:
-          cat = m.group(1)
-        else:
-          m = reH4.search(line)
-          if m is not None:
-            item = m.group(1)
-
-  if len(errors) != 0:
-    print()
-    print(fullPath)
-    for cat, item, message in errors:
-      print('  broken details HTML: %s: %s: %s' % (cat, item, message))
-    return True
-  else:
-    return False
-
-def checkClassSummaries(fullPath):
-  #print("check %s" % fullPath)
-
-  # TODO: only works with java7 generated javadocs now!
-  f = open(fullPath, encoding='UTF-8')
-
-  missing = []
-  broken = []
-  inThing = False
-  lastCaption = None
-  lastItem = None
-
-  desc = None
-
-  foundMethodDetail = False
-  lastMethodAnchor = None
-  lineCount = 0
-  
-  for line in f.readlines():
-    m = reMethodDetail.search(line)
-    lineCount += 1
-    if m is not None:
-      foundMethodDetail = True
-      #print('  got method detail')
-      continue
-
-    # prune methods that are just @Overrides of other interface/classes,
-    # they should be specified elsewhere, if they are e.g. jdk or 
-    # external classes we cannot inherit their docs anyway
-    if foundMethodDetail:
-      m = reMethodDetailAnchor.search(line) or reJ13MethodDetailAnchor.search(line)
-      if m is not None:
-        lastMethodAnchor = m.group(1)
-        continue
-      isOverrides = '>Overrides:<' in line or '>Specified by:<' in line
-      #print('check for removing @overridden method: %s; %s; %s' % (lastMethodAnchor, isOverrides, missing))
-      if isOverrides and ('Methods', lastMethodAnchor) in missing:
-        #print('removing @overridden method: %s' % lastMethodAnchor)
-        missing.remove(('Methods', lastMethodAnchor))
-
-    m = reCaption.search(line)
-    if m is not None:
-      lastCaption = m.group(1)
-      #print('    caption %s' % lastCaption)
-    else:
-      m = reJ8Caption.search(line)
-      if m is not None:
-        lastCaption = m.group(1)
-        if not lastCaption.endswith('s'):
-          lastCaption += 's'
-        #print('    caption %s' % lastCaption)
-
-    # Try to find the item in question (method/member name):
-    for matcher in (reTDLastNested, # nested classes
-                    reMethod, # methods etc.
-                    reColOne, # ctors etc.
-                    reMemberNameLink, # java 8
-                    reNestedClassMemberNameLink, # java 8, nested class
-                    reMemberNameOneLink): # java 8 ctors
-      m = matcher.search(line)
-      if m is not None:
-        lastItem = m.group(1)
-        #print('  found item %s; inThing=%s' % (lastItem, inThing))
-        break
-
-    lineLower = line.strip().lower()
-
-    if lineLower.find('<tr class="') != -1 or lineLower.find('<tr id="') != -1:
-      inThing = True
-      hasDesc = False
-      continue
-
-    if inThing:
-      if lineLower.find('</tr>') != -1:
-        #print('  end item %s; hasDesc %s' % (lastItem, hasDesc))
-        if not hasDesc:
-          if lastItem is None:
-            raise RuntimeError('failed to locate javadoc item in %s, line %d? last line: %s' % (fullPath, lineCount, line.rstrip()))
-          missing.append((lastCaption, unEscapeURL(lastItem)))
-          #print('    add missing; now %d: %s' % (len(missing), str(missing)))
-        inThing = False
-        continue
-      else:
-        if line.find('<div class="block">') != -1:
-          desc = []
-        if desc is not None:
-          desc.append(line)
-          if line.find('</div>') != -1:
-            desc = ''.join(desc)
-
-            try:
-              verifyHTML(desc)
-            except RuntimeError as e:
-              broken.append((lastCaption, lastItem, str(e)))
-              #print('FAIL: %s: %s: %s: %s' % (lastCaption, lastItem, e, desc))
-                            
-            desc = desc.replace('<div class="block">', '')
-            desc = desc.replace('</div>', '')
-            desc = desc.strip()
-            hasDesc = len(desc) > 0
-            #print('   thing %s: %s' % (lastItem, desc))
-
-            desc = None
-  f.close()
-  if len(missing) > 0 or len(broken) > 0:
-    print()
-    print(fullPath)
-    for (caption, item) in missing:
-      print('  missing %s: %s' % (caption, item))
-    for (caption, item, why) in broken:
-      print('  broken HTML: %s: %s: %s' % (caption, item, why))
-    return True
-  else:
-    return False
-  
-def checkSummary(fullPath):
-  printed = False
-  f = open(fullPath, encoding='UTF-8')
-  anyMissing = False
-  sawPackage = False
-  desc = []
-  lastHREF = None
-  for line in f.readlines():
-    lineLower = line.strip().lower()
-    if desc is not None:
-      # TODO: also detect missing description in overview-summary
-      if lineLower.startswith('package ') or lineLower.startswith('<h1 title="package" '):
-        sawPackage = True
-      elif sawPackage:
-        if lineLower.startswith('<table ') or lineLower.startswith('<b>see: ') or lineLower.startswith('<p>see:') or lineLower.startswith('</main>'):
-          desc = ' '.join(desc)
-          desc = reMarkup.sub(' ', desc)
-          desc = desc.strip()
-          if desc == '':
-            if not printed:
-              print()
-              print(fullPath)
-              printed = True
-            print('  no package description (missing package.html in src?)')
-            anyMissing = True
-          desc = None
-        else:
-          desc.append(lineLower)
-      
-    if lineLower in ('<td>&nbsp;</td>', '<td></td>', '<td class="collast">&nbsp;</td>'):
-      if not printed:
-        print()
-        print(fullPath)
-        printed = True
-      print('  missing description: %s' % unescapeHTML(lastHREF))
-      anyMissing = True
-    elif lineLower.find('licensed to the apache software foundation') != -1 or lineLower.find('copyright 2004 the apache software foundation') != -1:
-      if not printed:
-        print()
-        print(fullPath)
-        printed = True
-      print('  license-is-javadoc: %s' % unescapeHTML(lastHREF))
-      anyMissing = True
-    m = reHREF.search(line)
-    if m is not None:
-      lastHREF = m.group(1)
-  if desc is not None and fullPath.find('/overview-summary.html') == -1:
-    raise RuntimeError('BUG: failed to locate description in %s' % fullPath)
-  f.close()
-  return anyMissing
-
-def unEscapeURL(s):
-  # Not exhaustive!!
-  s = s.replace('%20', ' ')
-  s = s.replace('%5B', '[')
-  s = s.replace('%5D', ']')
-  return s
-
-def unescapeHTML(s):
-  s = s.replace('&lt;', '<')
-  s = s.replace('&gt;', '>')
-  s = s.replace('&amp;', '&')
-  return s
-
-def checkPackageSummaries(root, level='class'):
-  """
-  Just checks for blank summary lines in package-summary.html; returns
-  True if there are problems.
-  """
-
-  if level != 'class' and level != 'package' and level != 'method' and level != 'none':
-    print('unsupported level: %s, must be "class" or "package" or "method" or "none"' % level)
-    sys.exit(1)
-  
-  #for dirPath, dirNames, fileNames in os.walk('%s/lucene/build/docs/api' % root):
-
-  if False:
-    os.chdir(root)
-    print()
-    print('Run "ant javadocs" > javadocs.log...')
-    if os.system('ant javadocs > javadocs.log 2>&1'):
-      print('  FAILED')
-      sys.exit(1)
-    
-  anyMissing = False
-  if not os.path.isdir(root):
-    checkClassSummaries(root)
-    checkClassDetails(root)
-    sys.exit(0)
-    
-  for dirPath, dirNames, fileNames in os.walk(root):
-
-    if dirPath.find('/all/') != -1:
-      # These are dups (this is a bit risk, eg, root IS this /all/ directory..)
-      continue
-
-    if 'package-summary.html' in fileNames:
-      if (level == 'class' or level == 'method') and checkSummary('%s/package-summary.html' % dirPath):
-        anyMissing = True
-      for fileName in fileNames:
-        fullPath = '%s/%s' % (dirPath, fileName)
-        if not fileName.startswith('package-') and fileName.endswith('.html') and os.path.isfile(fullPath):
-          if level == 'method':
-            if checkClassSummaries(fullPath):
-              anyMissing = True
-          # always look for broken html, regardless of level supplied
-          if checkClassDetails(fullPath):
-            anyMissing = True
-              
-    if 'overview-summary.html' in fileNames:        
-      if level != 'none' and checkSummary('%s/overview-summary.html' % dirPath):
-        anyMissing = True
-
-  return anyMissing
-
-if __name__ == '__main__':
-  if len(sys.argv) < 2 or len(sys.argv) > 3:
-    print('usage: %s <dir> [none|package|class|method]' % sys.argv[0])
-    sys.exit(1)
-  if len(sys.argv) == 2:
-    level = 'class'
-  else:
-    level = sys.argv[2]
-  if checkPackageSummaries(sys.argv[1], level):
-    print()
-    print('Missing javadocs were found!')
-    sys.exit(1)
-  sys.exit(0)
diff --git a/dev-tools/scripts/smokeTestRelease.py b/dev-tools/scripts/smokeTestRelease.py
index 263287b..7feba04 100755
--- a/dev-tools/scripts/smokeTestRelease.py
+++ b/dev-tools/scripts/smokeTestRelease.py
@@ -39,7 +39,6 @@ from collections import defaultdict
 from collections import namedtuple
 from scriptutil import download
 
-import checkJavaDocs
 import checkJavadocLinks
 
 # This tool expects to find /lucene and /solr off the base URL.  You
@@ -668,7 +667,7 @@ def verifyUnpacked(java, project, artifact, unpackPath, gitRevision, version, te
 
       print('    generate javadocs w/ Java 11...')
       java.run_java11('ant javadocs', '%s/javadocs.log' % unpackPath)
-      checkJavadocpathFull('%s/build/docs' % unpackPath)
+      checkBrokenLinks('%s/build/docs' % unpackPath)
 
       if java.run_java12:
         print("    run tests w/ Java 12 and testArgs='%s'..." % testArgs)
@@ -678,7 +677,7 @@ def verifyUnpacked(java, project, artifact, unpackPath, gitRevision, version, te
 
         #print('    generate javadocs w/ Java 12...')
         #java.run_java12('ant javadocs', '%s/javadocs.log' % unpackPath)
-        #checkJavadocpathFull('%s/build/docs' % unpackPath)
+        #checkBrokenLinks('%s/build/docs' % unpackPath)
 
     else:
       os.chdir('solr')
@@ -689,7 +688,7 @@ def verifyUnpacked(java, project, artifact, unpackPath, gitRevision, version, te
       # test javadocs
       print('    generate javadocs w/ Java 11...')
       java.run_java11('ant clean javadocs', '%s/javadocs.log' % unpackPath)
-      checkJavadocpathFull('%s/solr/build/docs' % unpackPath, False)
+      checkBrokenLinks('%s/solr/build/docs')
 
       print('    test solr example w/ Java 11...')
       java.run_java11('ant clean server', '%s/antexample.log' % unpackPath)
@@ -701,7 +700,7 @@ def verifyUnpacked(java, project, artifact, unpackPath, gitRevision, version, te
 
         #print('    generate javadocs w/ Java 12...')
         #java.run_java12('ant clean javadocs', '%s/javadocs.log' % unpackPath)
-        #checkJavadocpathFull('%s/solr/build/docs' % unpackPath, False)
+        #checkBrokenLinks('%s/solr/build/docs' % unpackPath)
 
         print('    test solr example w/ Java 12...')
         java.run_java12('ant clean server', '%s/antexample.log' % unpackPath)
@@ -720,9 +719,6 @@ def verifyUnpacked(java, project, artifact, unpackPath, gitRevision, version, te
       if java.run_java12:
         testDemo(java.run_java12, isSrc, version, '12')
 
-      print('    check Lucene\'s javadoc JAR')
-      checkJavadocpath('%s/docs' % unpackPath)
-
     else:
       print('    copying unpacked distribution for Java 11 ...')
       java11UnpackPath = '%s-java11' % unpackPath
@@ -861,26 +857,8 @@ def testSolrExample(unpackPath, javaPath, isSrc):
   else:
     os.chdir(unpackPath)
     
-# the weaker check: we can use this on java6 for some checks,
-# but its generated HTML is hopelessly broken so we cannot run
-# the link checking that checkJavadocpathFull does.
-def checkJavadocpath(path, failOnMissing=True):
-  # check for level='package'
-  # we fail here if its screwed up
-  if failOnMissing and checkJavaDocs.checkPackageSummaries(path, 'package'):
-    raise RuntimeError('missing javadocs package summaries!')
-    
-  # now check for level='class'
-  if checkJavaDocs.checkPackageSummaries(path):
-    # disabled: RM cannot fix all this, see LUCENE-3887
-    # raise RuntimeError('javadoc problems')
-    print('\n***WARNING***: javadocs want to fail!\n')
-
-# full checks
-def checkJavadocpathFull(path, failOnMissing=True):
-  # check for missing, etc
-  checkJavadocpath(path, failOnMissing)
-
+# check for broken links
+def checkBrokenLinks(path):
   # also validate html/check for broken links
   if checkJavadocLinks.checkAll(path):
     raise RuntimeError('broken javadocs links found!')
diff --git a/gradle/documentation/render-javadoc.gradle b/gradle/documentation/render-javadoc.gradle
index a7a76ef..46bb867 100644
--- a/gradle/documentation/render-javadoc.gradle
+++ b/gradle/documentation/render-javadoc.gradle
@@ -22,6 +22,14 @@ import javax.annotation.Nullable
 
 allprojects {
   plugins.withType(JavaPlugin) {
+    configurations {
+      missingdoclet
+    }
+
+    dependencies {
+      missingdoclet "org.apache.lucene.tools:missing-doclet"
+    }
+
     ext {
       relativeDocPath = project.path.replaceFirst(/:\w+:/, "").replace(':', '/')
     }
@@ -76,6 +84,233 @@ allprojects {
         "https://docs.oracle.com/en/java/javase/11/docs/api/": javaJavadocPackages,
         "https://junit.org/junit4/javadoc/4.12/": junitJavadocPackages
     ]
+
+    // Set up custom doclet.
+    dependsOn configurations.missingdoclet
+    docletpath = configurations.missingdoclet
+  }
+}
+
+// Configure project-specific tweaks and to-dos.
+
+configure(project(":lucene:analysis:common")) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: fix missing javadocs
+    javadocMissingLevel = "class"
+    // TODO: clean up split packages
+    javadocMissingIgnore = [ "org.apache.lucene.analysis.standard" ]
+  }
+}
+
+configure([
+    project(":lucene:analysis:kuromoji"),
+    project(":lucene:analysis:nori"),
+    project(":lucene:analysis:opennlp"),
+    project(":lucene:analysis:smartcn"),
+    project(":lucene:benchmark"),
+    project(":lucene:codecs"),
+    project(":lucene:grouping"),
+    project(":lucene:highlighter"),
+    project(":lucene:luke"),
+    project(":lucene:monitor"),
+    project(":lucene:queries"),
+    project(":lucene:queryparser"),
+    project(":lucene:replicator"),
+    project(":lucene:spatial-extras"),
+  ]) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: fix missing javadocs
+    javadocMissingLevel = "class"
+  }
+}
+
+configure([
+    project(":lucene:analysis:icu"),
+    project(":lucene:analysis:morfologik"),
+    project(":lucene:analysis:phonetic"),
+    project(":lucene:analysis:stempel"),
+    project(":lucene:classification"),
+    project(":lucene:demo"),
+    project(":lucene:expressions"),
+    project(":lucene:facet"),
+    project(":lucene:join"),
+    project(":lucene:spatial3d"),
+    project(":lucene:suggest"),
+  ]) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: fix missing @param tags
+    javadocMissingLevel = "method"
+  }
+}
+
+configure(project(":lucene:analysis:icu")) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: clean up split packages
+    javadocMissingIgnore = [
+        "org.apache.lucene.collation",
+        "org.apache.lucene.collation.tokenattributes"
+    ]
+  }
+}
+
+configure(project(":lucene:backward-codecs")) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: fix missing @param tags
+    javadocMissingLevel = "method"
+    // TODO: clean up split packages
+    javadocMissingIgnore = [
+        "org.apache.lucene.codecs",
+        "org.apache.lucene.codecs.lucene50",
+        "org.apache.lucene.codecs.lucene60",
+        "org.apache.lucene.codecs.lucene80",
+        "org.apache.lucene.codecs.lucene84",
+        "org.apache.lucene.codecs.lucene86"
+    ]
+  }
+}
+
+configure(project(":lucene:test-framework")) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: fix missing javadocs
+    javadocMissingLevel = "class"
+    // TODO: clean up split packages
+    javadocMissingIgnore = [
+        "org.apache.lucene.analysis",
+        "org.apache.lucene.analysis.standard",
+        "org.apache.lucene.codecs",
+        "org.apache.lucene.codecs.blockterms",
+        "org.apache.lucene.codecs.bloom",
+        "org.apache.lucene.codecs.compressing",
+        "org.apache.lucene.codecs.uniformsplit",
+        "org.apache.lucene.codecs.uniformsplit.sharedterms",
+        "org.apache.lucene.geo",
+        "org.apache.lucene.index",
+        "org.apache.lucene.search",
+        "org.apache.lucene.search.similarities",
+        "org.apache.lucene.search.spans",
+        "org.apache.lucene.store",
+        "org.apache.lucene.util",
+        "org.apache.lucene.util.automaton",
+        "org.apache.lucene.util.fst"
+    ]
+  }
+}
+
+configure(project(":lucene:sandbox")) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: fix missing javadocs
+    javadocMissingLevel = "class"
+    // TODO: clean up split packages
+    javadocMissingIgnore = [
+        "org.apache.lucene.search",
+        "org.apache.lucene.document"
+    ]
+  }
+}
+
+configure(project(":lucene:misc")) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: fix missing javadocs
+    javadocMissingLevel = "class"
+    // TODO: clean up split packages
+    javadocMissingIgnore = [
+        "org.apache.lucene.search",
+        "org.apache.lucene.search.similarity",
+        "org.apache.lucene.util",
+        "org.apache.lucene.util.fst",
+        "org.apache.lucene.store",
+        "org.apache.lucene.document",
+        "org.apache.lucene.index"
+    ]
+  }
+}
+
+configure(project(":lucene:core")) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: fix missing javadocs
+    javadocMissingLevel = "class"
+    // some packages are fixed already
+    javadocMissingMethod = [
+        "org.apache.lucene.util.automaton",
+        "org.apache.lucene.analysis",
+        "org.apache.lucene.analysis.standard",
+        "org.apache.lucene.analysis.tokenattributes",
+        "org.apache.lucene.document",
+        "org.apache.lucene.search.similarities",
+        "org.apache.lucene.index",
+        "org.apache.lucene.codecs",
+        "org.apache.lucene.codecs.lucene50",
+        "org.apache.lucene.codecs.lucene60",
+        "org.apache.lucene.codecs.lucene80",
+        "org.apache.lucene.codecs.lucene84",
+        "org.apache.lucene.codecs.lucene86",
+        "org.apache.lucene.codecs.lucene87",
+        "org.apache.lucene.codecs.perfield"
+    ]
+  }
+}
+
+configure(project(":solr").allprojects) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: fix missing javadocs
+    javadocMissingLevel = "package"
+  }
+}
+
+configure(project(":solr:contrib:velocity")) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: clean up split packages
+    javadocMissingIgnore = [ "org.apache.solr.response" ]
+  }
+}
+
+configure(project(":solr:contrib:analysis-extras")) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: clean up split packages
+    javadocMissingIgnore = [
+        "org.apache.solr.schema",
+        "org.apache.solr.update.processor"
+    ]
+  }
+}
+
+configure(project(":solr:contrib:analytics")) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: clean up split packages
+    javadocMissingIgnore = [
+        "org.apache.solr.handler",
+        "org.apache.solr.handler.component",
+        "org.apache.solr.response"
+    ]
+  }
+}
+
+configure(project(":solr:contrib:langid")) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: clean up split packages
+    javadocMissingIgnore = [ "org.apache.solr.update.processor" ]
+  }
+}
+
+configure(project(":solr:solrj")) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: clean up split packages
+    javadocMissingIgnore = [ "org.apache.solr.client.solrj.embedded" ]
+  }
+}
+
+configure(project(":solr:test-framework")) {
+  project.tasks.withType(RenderJavadocTask) {
+    // TODO: clean up split packages
+    javadocMissingIgnore = [
+        "org.apache.solr",
+        "org.apache.solr.analysis",
+        "org.apache.solr.cloud",
+        "org.apache.solr.core",
+        "org.apache.solr.handler.component",
+        "org.apache.solr.update.processor",
+        "org.apache.solr.util"
+    ]
   }
 }
 
@@ -136,6 +371,9 @@ class RenderJavadocTask extends DefaultTask {
   @CompileClasspath
   FileCollection classpath
 
+  @CompileClasspath
+  FileCollection docletpath
+
   @Input
   String title
 
@@ -154,6 +392,19 @@ class RenderJavadocTask extends DefaultTask {
   @Input
   def solrDocUrl = "${->project.solrDocUrl}"
 
+  // default is to require full javadocs
+  @Input
+  String javadocMissingLevel = "parameter"
+
+  // anything in these packages is checked with level=method. This allows iteratively fixing one package at a time.
+  @Input
+  List<String> javadocMissingMethod = []
+
+  // default is not to ignore any elements, should only be used to workaround split packages
+  @Input
+  List<String> javadocMissingIgnore = []
+
+
   @Nullable
   @Optional
   @Input
@@ -207,6 +458,18 @@ class RenderJavadocTask extends DefaultTask {
     opts << [ '-tag', 'lucene.internal:a:NOTE: This API is for internal purposes only and might change in incompatible ways in the next release.' ]
     opts << [ '-tag', "lucene.spi:t:SPI Name (case-insensitive: if the name is 'htmlStrip', 'htmlstrip' can be used when looking up the service)." ]
 
+    opts << [ '-doclet', "org.apache.lucene.missingdoclet.MissingDoclet" ]
+    opts << [ '-docletpath', docletpath.asPath ]
+    opts << [ '--missing-level', javadocMissingLevel ]
+    if (javadocMissingIgnore) {
+      opts << [ '--missing-ignore', String.join(',', javadocMissingIgnore) ]
+    }
+    if (javadocMissingMethod) {
+      opts << [ '--missing-method', String.join(',', javadocMissingMethod) ]
+    }
+
+    opts << [ '-quiet' ]
+
     def allOfflineLinks = [:]
     allOfflineLinks.putAll(offlineLinks)
 
diff --git a/gradle/validation/validate-source-patterns.gradle b/gradle/validation/validate-source-patterns.gradle
index ce27e2d..b121f42 100644
--- a/gradle/validation/validate-source-patterns.gradle
+++ b/gradle/validation/validate-source-patterns.gradle
@@ -19,8 +19,39 @@
 // the ant/groovy script we already have.
 
 configure(rootProject) {
-  configurations {
-    checkSourceDeps
+  task("validateSourcePatterns", type: ValidateSourcePatternsTask) {
+    group = 'Verification'
+    description = 'Validate Source Patterns'
+    
+    sourceFiles = project.fileTree(project.rootDir) {
+      [
+        'java', 'jflex', 'py', 'pl', 'g4', 'jj', 'html', 'js',
+        'css', 'xml', 'xsl', 'vm', 'sh', 'cmd', 'bat', 'policy',
+        'properties', 'mdtext', 'groovy', 'gradle',
+        'template', 'adoc', 'json',
+      ].each{
+        include "lucene/**/*.${it}"
+        include "solr/**/*.${it}"
+        include "dev-tools/**/*.${it}"
+        include "gradle/**/*.${it}"
+        include "*.${it}"
+      }
+      // TODO: For now we don't scan txt / md files, so we
+      // check licenses in top-level folders separately:
+      include '*.txt'
+      include '*/*.txt'
+      include '*.md'
+      include '*/*.md'
+      // excludes:
+      exclude '**/build/**'
+      exclude '**/dist/**'
+      exclude 'dev-tools/missing-doclet/src/**/*.java' // <-- TODO: remove once we allow "var" on master
+      exclude 'lucene/benchmark/work/**'
+      exclude 'lucene/benchmark/temp/**'
+      exclude '**/CheckLoggingConfiguration.java'
+      exclude 'solr/core/src/test/org/apache/hadoop/**'
+      exclude '**/validate-source-patterns.gradle' // ourselves :-)
+    }
   }
 
   dependencies {
@@ -38,4 +69,4 @@ configure(rootProject) {
       ant.groovy(src: rootProject.file("gradle/validation/validate-source-patterns/check-source-patterns.groovy"))
     }
   }
-}
\ No newline at end of file
+}
diff --git a/lucene/analysis/common/build.gradle b/lucene/analysis/common/build.gradle
index ff5857b..a44152c 100644
--- a/lucene/analysis/common/build.gradle
+++ b/lucene/analysis/common/build.gradle
@@ -23,4 +23,3 @@ dependencies {
   api project(':lucene:core')
   testImplementation project(':lucene:test-framework')
 }
-
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/compound/hyphenation/TernaryTree.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/compound/hyphenation/TernaryTree.java
index a331d2a..6d1d71a 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/compound/hyphenation/TernaryTree.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/compound/hyphenation/TernaryTree.java
@@ -456,6 +456,10 @@ public class TernaryTree implements Cloneable {
     return new Iterator();
   }
 
+  /**
+   * Enumeration over TST keys
+   * @lucene.internal
+   */
   public class Iterator implements Enumeration<String> {
 
     /**
diff --git a/lucene/analysis/nori/build.gradle b/lucene/analysis/nori/build.gradle
index 60fe372..430673c 100644
--- a/lucene/analysis/nori/build.gradle
+++ b/lucene/analysis/nori/build.gradle
@@ -25,3 +25,4 @@ dependencies {
   
   testImplementation project(':lucene:test-framework')
 }
+
diff --git a/lucene/backward-codecs/src/java/org/apache/lucene/codecs/Placeholder.java b/lucene/backward-codecs/src/java/org/apache/lucene/codecs/Placeholder.java
index f359369..d615da3 100644
--- a/lucene/backward-codecs/src/java/org/apache/lucene/codecs/Placeholder.java
+++ b/lucene/backward-codecs/src/java/org/apache/lucene/codecs/Placeholder.java
@@ -18,5 +18,6 @@ package org.apache.lucene.codecs;
 
 /** Remove this file when adding back compat codecs */
 public class Placeholder {
-  
+  // no instance
+  private Placeholder() {}
 }
diff --git a/lucene/benchmark/build.gradle b/lucene/benchmark/build.gradle
index 4b34cce..793fbd6 100644
--- a/lucene/benchmark/build.gradle
+++ b/lucene/benchmark/build.gradle
@@ -153,4 +153,4 @@ task getReuters(type: Download) {
     }
   }
   outputs.dir finalPath
-}
\ No newline at end of file
+}
diff --git a/lucene/classification/src/java/org/apache/lucene/classification/CachingNaiveBayesClassifier.java b/lucene/classification/src/java/org/apache/lucene/classification/CachingNaiveBayesClassifier.java
index b069e19..700e5f7 100644
--- a/lucene/classification/src/java/org/apache/lucene/classification/CachingNaiveBayesClassifier.java
+++ b/lucene/classification/src/java/org/apache/lucene/classification/CachingNaiveBayesClassifier.java
@@ -77,6 +77,7 @@ public class CachingNaiveBayesClassifier extends SimpleNaiveBayesClassifier {
   }
 
 
+  /** Transforms values into a range between 0 and 1 */
   protected List<ClassificationResult<BytesRef>> assignClassNormalizedList(String inputDocument) throws IOException {
     String[] tokenizedText = tokenize(inputDocument);
 
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/uniformsplit/sharedterms/STUniformSplitTermsWriter.java b/lucene/codecs/src/java/org/apache/lucene/codecs/uniformsplit/sharedterms/STUniformSplitTermsWriter.java
index ca15d6a..428e4f9 100755
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/uniformsplit/sharedterms/STUniformSplitTermsWriter.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/uniformsplit/sharedterms/STUniformSplitTermsWriter.java
@@ -335,7 +335,7 @@ public class STUniformSplitTermsWriter extends UniformSplitTermsWriter {
     Collection<FieldMetadata> writeSharedTerms(STBlockWriter blockWriter, IndexDictionary.Builder dictionaryBuilder) throws IOException;
   }
 
-  protected class SegmentPostings {
+  final class SegmentPostings {
 
     final int segmentIndex;
     final BlockTermState termState;
diff --git a/lucene/core/src/java/org/apache/lucene/search/MultiCollectorManager.java b/lucene/core/src/java/org/apache/lucene/search/MultiCollectorManager.java
index 6e73c54..611f518 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MultiCollectorManager.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MultiCollectorManager.java
@@ -58,6 +58,7 @@ public class MultiCollectorManager implements CollectorManager<MultiCollectorMan
     return results;
   }
 
+  /** Wraps multiple collectors for processing */
   public class Collectors implements Collector {
 
     private final Collector[] collectors;
@@ -86,6 +87,10 @@ public class MultiCollectorManager implements CollectorManager<MultiCollectorMan
       return scoreMode;
     }
 
+    /**
+     * Wraps multiple leaf collectors and delegates collection across each one
+     * @lucene.internal
+     */
     public class LeafCollectors implements LeafCollector {
 
       private final LeafCollector[] leafCollectors;
diff --git a/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF1EXP.java b/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF1EXP.java
index ca5c42b..1879109 100644
--- a/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF1EXP.java
+++ b/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF1EXP.java
@@ -128,4 +128,4 @@ public class AxiomaticF1EXP extends Axiomatic {
         Explanation.match((float) stats.getDocFreq(),
             "n, number of documents containing term"));
   };
-}
\ No newline at end of file
+}
diff --git a/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF1LOG.java b/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF1LOG.java
index 6ef3587..5f8559f 100644
--- a/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF1LOG.java
+++ b/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF1LOG.java
@@ -119,4 +119,4 @@ public class AxiomaticF1LOG extends Axiomatic {
         Explanation.match((float) stats.getDocFreq(),
             "n, number of documents containing term"));
   };
-}
\ No newline at end of file
+}
diff --git a/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF2EXP.java b/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF2EXP.java
index bd28048..4446258 100644
--- a/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF2EXP.java
+++ b/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF2EXP.java
@@ -127,4 +127,4 @@ public class AxiomaticF2EXP extends Axiomatic {
         Explanation.match((float) stats.getDocFreq(),
             "n, number of documents containing term"));
   };
-}
\ No newline at end of file
+}
diff --git a/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF2LOG.java b/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF2LOG.java
index 4780d1e..5568737 100644
--- a/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF2LOG.java
+++ b/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF2LOG.java
@@ -118,4 +118,4 @@ public class AxiomaticF2LOG extends Axiomatic {
         Explanation.match((float) stats.getDocFreq(),
             "n, number of documents containing term"));
   };
-}
\ No newline at end of file
+}
diff --git a/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF3EXP.java b/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF3EXP.java
index a54c754..b9ed346 100644
--- a/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF3EXP.java
+++ b/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF3EXP.java
@@ -122,4 +122,4 @@ public class AxiomaticF3EXP extends Axiomatic {
         Explanation.match((float) stats.getDocFreq(),
             "n, number of documents containing term"));
   };
-}
\ No newline at end of file
+}
diff --git a/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF3LOG.java b/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF3LOG.java
index 194b70a..ea772e0 100644
--- a/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF3LOG.java
+++ b/lucene/core/src/java/org/apache/lucene/search/similarities/AxiomaticF3LOG.java
@@ -110,4 +110,4 @@ public class AxiomaticF3LOG extends Axiomatic {
         Explanation.match((float) stats.getDocFreq(),
             "n, number of documents containing term"));
   };
-}
\ No newline at end of file
+}
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanContainingQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanContainingQuery.java
index 6366299..f3909bb 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanContainingQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanContainingQuery.java
@@ -51,6 +51,10 @@ public final class SpanContainingQuery extends SpanContainQuery {
                                       bigWeight, littleWeight, boost);
   }
 
+  /**
+   * Creates SpanContainingQuery scorer instances
+   * @lucene.internal
+   */
   public class SpanContainingWeight extends SpanContainWeight {
 
     public SpanContainingWeight(IndexSearcher searcher, Map<Term, TermStates> terms,
@@ -123,4 +127,4 @@ public final class SpanContainingQuery extends SpanContainQuery {
     }
 
   }
-}
\ No newline at end of file
+}
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java
index 2f219bf..900f7b6 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java
@@ -187,6 +187,10 @@ public class SpanNearQuery extends SpanQuery implements Cloneable {
     return new SpanNearWeight(subWeights, searcher, scoreMode.needsScores() ? getTermStates(subWeights) : null, boost);
   }
 
+  /**
+   * Creates SpanNearQuery scorer instances
+   * @lucene.internal
+   */
   public class SpanNearWeight extends SpanWeight {
 
     final List<SpanWeight> subWeights;
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java
index 5d998fe..bad825f 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java
@@ -106,6 +106,10 @@ public final class SpanNotQuery extends SpanQuery {
                                   includeWeight, excludeWeight, boost);
   }
 
+  /**
+   * Creates SpanNotQuery scorer instances
+   * @lucene.internal
+   */
   public class SpanNotWeight extends SpanWeight {
 
     final SpanWeight includeWeight;
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java
index 5f589e1..0a8e89e 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java
@@ -136,6 +136,10 @@ public final class SpanOrQuery extends SpanQuery {
     return new SpanOrWeight(searcher, scoreMode.needsScores() ? getTermStates(subWeights) : null, subWeights, boost);
   }
 
+  /**
+   * Creates SpanOrQuery scorer instances
+   * @lucene.internal
+   */
   public class SpanOrWeight extends SpanWeight {
 
     final List<SpanWeight> subWeights;
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java
index 3e40c64..e2d09c2 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java
@@ -74,6 +74,10 @@ public abstract class SpanPositionCheckQuery extends SpanQuery implements Clonea
     return new SpanPositionCheckWeight(matchWeight, searcher, scoreMode.needsScores() ? getTermStates(matchWeight) : null, boost);
   }
 
+  /**
+   * Creates SpanPositionCheckQuery scorer instances
+   * @lucene.internal
+   */
   public class SpanPositionCheckWeight extends SpanWeight {
 
     final SpanWeight matchWeight;
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
index c86e7b7..dda3f44 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
@@ -91,6 +91,10 @@ public class SpanTermQuery extends SpanQuery {
     }
   }
 
+  /**
+   * Creates SpanTermQuery scorer instances
+   * @lucene.internal
+   */
   public class SpanTermWeight extends SpanWeight {
 
     final TermStates termStates;
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanWithinQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanWithinQuery.java
index fba85fe..dfe8c83 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanWithinQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanWithinQuery.java
@@ -52,6 +52,10 @@ public final class SpanWithinQuery extends SpanContainQuery {
                                       bigWeight, littleWeight, boost);
   }
 
+  /**
+   * Creates SpanWithinQuery scorer instances
+   * @lucene.internal
+   */
   public class SpanWithinWeight extends SpanContainWeight {
 
     public SpanWithinWeight(IndexSearcher searcher, Map<Term, TermStates> terms,
@@ -125,4 +129,4 @@ public final class SpanWithinQuery extends SpanContainQuery {
 
   }
 
-}
\ No newline at end of file
+}
diff --git a/lucene/core/src/java/org/apache/lucene/util/PagedBytes.java b/lucene/core/src/java/org/apache/lucene/util/PagedBytes.java
index e07046c..6127864 100644
--- a/lucene/core/src/java/org/apache/lucene/util/PagedBytes.java
+++ b/lucene/core/src/java/org/apache/lucene/util/PagedBytes.java
@@ -282,6 +282,10 @@ public final class PagedBytes implements Accountable {
     return pointer;
   }
 
+  /**
+   * Input that transparently iterates over pages
+   * @lucene.internal
+   */
   public final class PagedBytesDataInput extends DataInput {
     private int currentBlockIndex;
     private int currentBlockUpto;
@@ -350,6 +354,10 @@ public final class PagedBytes implements Accountable {
     }
   }
 
+  /**
+   * Output that transparently spills to new pages as necessary
+   * @lucene.internal
+   */
   public final class PagedBytesDataOutput extends DataOutput {
     @Override
     public void writeByte(byte b) {
diff --git a/lucene/grouping/build.gradle b/lucene/grouping/build.gradle
index b0838e3..6e71964 100644
--- a/lucene/grouping/build.gradle
+++ b/lucene/grouping/build.gradle
@@ -26,4 +26,4 @@ dependencies {
   implementation project(':lucene:queries')
 
   testImplementation project(':lucene:test-framework')
-}
\ No newline at end of file
+}
diff --git a/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java b/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java
index dacee10..705e0cc 100644
--- a/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java
+++ b/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java
@@ -629,6 +629,7 @@ public class MemoryIndex {
 
   /**
    * Set the Similarity to be used for calculating field norms
+   * @param similarity instance with custom {@link Similarity#computeNorm} implementation
    */
   public void setSimilarity(Similarity similarity) {
     if (frozen)
diff --git a/lucene/misc/build.gradle b/lucene/misc/build.gradle
index bdf575d..11758f7 100644
--- a/lucene/misc/build.gradle
+++ b/lucene/misc/build.gradle
@@ -22,4 +22,4 @@ description = 'Index tools and other miscellaneous code'
 dependencies {
   api project(':lucene:core')
   testImplementation project(':lucene:test-framework')
-}
\ No newline at end of file
+}
diff --git a/lucene/misc/src/java/org/apache/lucene/document/LazyDocument.java b/lucene/misc/src/java/org/apache/lucene/document/LazyDocument.java
index 7c5690e..1f2cfe8 100644
--- a/lucene/misc/src/java/org/apache/lucene/document/LazyDocument.java
+++ b/lucene/misc/src/java/org/apache/lucene/document/LazyDocument.java
@@ -125,6 +125,7 @@ public class LazyDocument {
 
 
   /** 
+   * Lazy-loaded field
    * @lucene.internal 
    */
   public class LazyField implements IndexableField {
diff --git a/lucene/queries/build.gradle b/lucene/queries/build.gradle
index 64c2bf4..bd56a4d 100644
--- a/lucene/queries/build.gradle
+++ b/lucene/queries/build.gradle
@@ -24,4 +24,5 @@ dependencies {
 
   testImplementation project(':lucene:test-framework')
   testImplementation project(':lucene:expressions')
-}
\ No newline at end of file
+}
+
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionQuery.java
index c804523..79a9ae5 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionQuery.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionQuery.java
@@ -53,6 +53,10 @@ public class FunctionQuery extends Query {
     return func;
   }
 
+  /**
+   * Creates FunctionQuery scorer instances
+   * @lucene.internal
+   */
   protected class FunctionWeight extends Weight {
     protected final IndexSearcher searcher;
     protected final float boost;
@@ -87,6 +91,10 @@ public class FunctionQuery extends Query {
     visitor.visitLeaf(this);
   }
 
+  /**
+   * Scores all documents, applying the function to each document
+   * @lucene.internal
+   */
   protected class AllScorer extends Scorer {
     final IndexReader reader;
     final FunctionWeight weight;
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/MultiFunction.java b/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/MultiFunction.java
index 591aa2c..2ff577e 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/MultiFunction.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/MultiFunction.java
@@ -121,6 +121,7 @@ public abstract class MultiFunction extends ValueSource {
     return valsArr;
   }
 
+  /** Base implementation that wraps multiple sources */
   public class Values extends FunctionValues {
     final FunctionValues[] valsArr;
 
diff --git a/lucene/queryparser/build.gradle b/lucene/queryparser/build.gradle
index 077eb24..365a999 100644
--- a/lucene/queryparser/build.gradle
+++ b/lucene/queryparser/build.gradle
@@ -26,3 +26,5 @@ dependencies {
 
   testImplementation project(':lucene:test-framework')
 }
+
+
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/precedence/processors/package-info.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/precedence/processors/package-info.java
new file mode 100644
index 0000000..5d0cf3c
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/precedence/processors/package-info.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * Lucene Precedence Query Parser Processors
+ *
+ * <p>
+ * This package contains the 2 {@link org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessor}s used by
+ * {@link org.apache.lucene.queryparser.flexible.precedence.PrecedenceQueryParser}.
+ * </p>
+ * <p>
+ * {@link org.apache.lucene.queryparser.flexible.precedence.processors.BooleanModifiersQueryNodeProcessor}: this processor
+ * is used to apply {@link org.apache.lucene.queryparser.flexible.core.nodes.ModifierQueryNode}s on
+ * {@link org.apache.lucene.queryparser.flexible.core.nodes.BooleanQueryNode} children according to the boolean type
+ * or the default operator.
+ * </p>
+ * <p>
+ * {@link org.apache.lucene.queryparser.flexible.precedence.processors.PrecedenceQueryNodeProcessorPipeline}: this
+ * processor pipeline is used by {@link org.apache.lucene.queryparser.flexible.precedence.PrecedenceQueryParser}. It extends
+ * {@link org.apache.lucene.queryparser.flexible.standard.processors.StandardQueryNodeProcessorPipeline} and rearrange
+ * the pipeline so the boolean precedence is processed correctly. Check {@link org.apache.lucene.queryparser.flexible.precedence.processors.PrecedenceQueryNodeProcessorPipeline}
+ * for more details. 
+ * </p>
+ */
+package org.apache.lucene.queryparser.flexible.precedence.processors;
\ No newline at end of file
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/precedence/processors/package.html b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/precedence/processors/package.html
deleted file mode 100644
index 1c4e093..0000000
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/precedence/processors/package.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<!--
- 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.
--->
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-</head>
-<body>
-
-Processors used by Precedence Query Parser
-
-<h2>Lucene Precedence Query Parser Processors</h2>
-
-<p>
-This package contains the 2 {@link org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessor}s used by
-{@link org.apache.lucene.queryparser.flexible.precedence.PrecedenceQueryParser}.
-</p>
-<p>
-{@link org.apache.lucene.queryparser.flexible.precedence.processors.BooleanModifiersQueryNodeProcessor}: this processor
-is used to apply {@link org.apache.lucene.queryparser.flexible.core.nodes.ModifierQueryNode}s on
-{@link org.apache.lucene.queryparser.flexible.core.nodes.BooleanQueryNode} children according to the boolean type
-or the default operator.
-</p>
-<p>
-{@link org.apache.lucene.queryparser.flexible.precedence.processors.PrecedenceQueryNodeProcessorPipeline}: this
-processor pipeline is used by {@link org.apache.lucene.queryparser.flexible.precedence.PrecedenceQueryParser}. It extends
-{@link org.apache.lucene.queryparser.flexible.standard.processors.StandardQueryNodeProcessorPipeline} and rearrange
-the pipeline so the boolean precedence is processed correctly. Check {@link org.apache.lucene.queryparser.flexible.precedence.processors.PrecedenceQueryNodeProcessorPipeline}
-for more details. 
-</p>
-
-</body>
-</html>
diff --git a/lucene/replicator/build.gradle b/lucene/replicator/build.gradle
index 32d5cc7..973c77f 100644
--- a/lucene/replicator/build.gradle
+++ b/lucene/replicator/build.gradle
@@ -36,3 +36,4 @@ dependencies {
 
   testImplementation project(':lucene:test-framework')
 }
+
diff --git a/lucene/spatial-extras/build.gradle b/lucene/spatial-extras/build.gradle
index 2766f7b..83889d3 100644
--- a/lucene/spatial-extras/build.gradle
+++ b/lucene/spatial-extras/build.gradle
@@ -31,3 +31,5 @@ dependencies {
   testImplementation 'org.locationtech.jts:jts-core'
   testImplementation 'org.locationtech.spatial4j:spatial4j::tests'
 }
+
+
diff --git a/solr/build.gradle b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package-info.java
similarity index 90%
copy from solr/build.gradle
copy to lucene/spatial-extras/src/java/org/apache/lucene/spatial/package-info.java
index 9edc4d1..ce3163c 100644
--- a/solr/build.gradle
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package-info.java
@@ -15,8 +15,5 @@
  * limitations under the License.
  */
 
-description = 'Parent project for Apache Solr'
-
-subprojects {
-  group "org.apache.solr"
-}
\ No newline at end of file
+/** Lucene advanced spatial search */
+package org.apache.lucene.spatial;
\ No newline at end of file
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package.html b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package.html
deleted file mode 100644
index b109f3a..0000000
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<!--
- 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.
--->
-<!-- not a package-info.java, because we already defined this package in spatial/ -->
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-</head>
-<body>
-Lucene advanced spatial search
-</body>
-</html>
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
index 99a5a4a..10b24a2 100644
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
@@ -157,6 +157,7 @@ public abstract class PrefixTreeStrategy extends SpatialStrategy {
     return new Field[]{field};
   }
 
+  /** Tokenstream for indexing cells of a shape */
   public class ShapeTokenStream extends BytesRefIteratorTokenStream {
 
     public void setShape(Shape shape) {
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java
index e060302..2fad4e7 100644
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java
@@ -265,6 +265,7 @@ public class QuadPrefixTree extends LegacyPrefixTree {
     // if we actually use the range property in the query, this could be useful
   }
 
+  /** individual QuadPrefixTree grid cell */
   protected class QuadCell extends LegacyCell {
 
     QuadCell(byte[] bytes, int off, int len) {
diff --git a/solr/build.gradle b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package-info.java
similarity index 90%
copy from solr/build.gradle
copy to lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package-info.java
index 9edc4d1..21f90eb 100644
--- a/solr/build.gradle
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package-info.java
@@ -15,8 +15,5 @@
  * limitations under the License.
  */
 
-description = 'Parent project for Apache Solr'
-
-subprojects {
-  group "org.apache.solr"
-}
\ No newline at end of file
+/** Advanced spatial utilities. */
+package org.apache.lucene.spatial.util;
\ No newline at end of file
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package.html b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package.html
deleted file mode 100644
index 83d9975..0000000
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<!--
- 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.
--->
-<!-- not a package-info.java, because we already defined this package in spatial/ -->
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-</head>
-<body>
-Advanced spatial utilities. 
-</body>
-</html>
diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/BaseTermVectorsFormatTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/index/BaseTermVectorsFormatTestCase.java
index 0955996..0e4e869 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/index/BaseTermVectorsFormatTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/index/BaseTermVectorsFormatTestCase.java
@@ -332,6 +332,7 @@ public abstract class BaseTermVectorsFormatTestCase extends BaseIndexFileFormatT
 
   }
 
+  /** Randomly generated document: call toDocument to index it */
   protected class RandomDocument {
 
     private final String[] fieldNames;
@@ -366,6 +367,7 @@ public abstract class BaseTermVectorsFormatTestCase extends BaseIndexFileFormatT
 
   }
 
+  /** Factory for generating random documents, call newDocument to generate each one */
   protected class RandomDocumentFactory {
 
     private final String[] fieldNames;
diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/PointsStackTracker.java b/lucene/test-framework/src/java/org/apache/lucene/index/PointsStackTracker.java
index 5f3535d..9a2fa9f 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/index/PointsStackTracker.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/index/PointsStackTracker.java
@@ -31,6 +31,7 @@ public class PointsStackTracker {
 
   public final List<Cell> stack = new ArrayList<>();
 
+  /** Individual BKD stack frame */
   public class Cell {
     public final byte[] minPackedValue;
     public final byte[] maxPackedValue;
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java b/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
index a8f1b7d..cd83f44 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
@@ -197,6 +197,7 @@ public abstract class ShardSearchingTestBase extends LuceneTestCase {
     return stats;
   }
 
+  /** Simulated shard node under test */
   protected final class NodeState implements Closeable {
     public final Directory dir;
     public final IndexWriter writer;
diff --git a/settings.gradle b/settings.gradle
index fb85047..4ea032c 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+includeBuild("dev-tools/missing-doclet")
 
 include "lucene:analysis:common"
 include "lucene:analysis:icu"
diff --git a/solr/build.gradle b/solr/build.gradle
index 9edc4d1..6096174 100644
--- a/solr/build.gradle
+++ b/solr/build.gradle
@@ -19,4 +19,6 @@ description = 'Parent project for Apache Solr'
 
 subprojects {
   group "org.apache.solr"
-}
\ No newline at end of file
+}
+
+
diff --git a/solr/contrib/analysis-extras/build.gradle b/solr/contrib/analysis-extras/build.gradle
index c39629a..8e6ddd0 100644
--- a/solr/contrib/analysis-extras/build.gradle
+++ b/solr/contrib/analysis-extras/build.gradle
@@ -32,4 +32,3 @@ dependencies {
 
   testImplementation project(':solr:test-framework')
 }
-
diff --git a/solr/build.gradle b/solr/core/src/java/org/apache/solr/query/package-info.java
similarity index 90%
copy from solr/build.gradle
copy to solr/core/src/java/org/apache/solr/query/package-info.java
index 9edc4d1..1bc0840 100644
--- a/solr/build.gradle
+++ b/solr/core/src/java/org/apache/solr/query/package-info.java
@@ -15,8 +15,7 @@
  * limitations under the License.
  */
 
-description = 'Parent project for Apache Solr'
-
-subprojects {
-  group "org.apache.solr"
-}
\ No newline at end of file
+/**
+ * Solr Queries
+ */
+package org.apache.solr.query;
\ No newline at end of file
diff --git a/solr/core/src/java/org/apache/solr/query/package.html b/solr/core/src/java/org/apache/solr/query/package.html
deleted file mode 100644
index 03ecf5f..0000000
--- a/solr/core/src/java/org/apache/solr/query/package.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<!--
- 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.
--->
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-</head>
-<body>
-<p>
-Solr Queries
-</p>
-</body>
-</html>
diff --git a/solr/build.gradle b/solr/core/src/java/org/apache/solr/request/json/package-info.java
similarity index 90%
copy from solr/build.gradle
copy to solr/core/src/java/org/apache/solr/request/json/package-info.java
index 9edc4d1..2a3060d 100644
--- a/solr/build.gradle
+++ b/solr/core/src/java/org/apache/solr/request/json/package-info.java
@@ -15,8 +15,7 @@
  * limitations under the License.
  */
 
-description = 'Parent project for Apache Solr'
-
-subprojects {
-  group "org.apache.solr"
-}
\ No newline at end of file
+/**
+ * JSON related classes
+ */
+package org.apache.solr.request.json;
\ No newline at end of file
diff --git a/solr/core/src/java/org/apache/solr/request/json/package.html b/solr/core/src/java/org/apache/solr/request/json/package.html
deleted file mode 100644
index d87e4a4..0000000
--- a/solr/core/src/java/org/apache/solr/request/json/package.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<!--
- 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.
--->
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-</head>
-<body>
-<p>
-JSON related classes
-</p>
-</body>
-</html>
diff --git a/solr/build.gradle b/solr/core/src/java/org/apache/solr/request/macro/package-info.java
similarity index 89%
copy from solr/build.gradle
copy to solr/core/src/java/org/apache/solr/request/macro/package-info.java
index 9edc4d1..222f4c6 100644
--- a/solr/build.gradle
+++ b/solr/core/src/java/org/apache/solr/request/macro/package-info.java
@@ -15,8 +15,7 @@
  * limitations under the License.
  */
 
-description = 'Parent project for Apache Solr'
-
-subprojects {
-  group "org.apache.solr"
-}
\ No newline at end of file
+/**
+ * Parameter substitution / macro expansion.
+ */
+package org.apache.solr.request.macro;
\ No newline at end of file
diff --git a/solr/core/src/java/org/apache/solr/request/macro/package.html b/solr/core/src/java/org/apache/solr/request/macro/package.html
deleted file mode 100644
index 21856b4..0000000
--- a/solr/core/src/java/org/apache/solr/request/macro/package.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<!--
- 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.
--->
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-</head>
-<body>
-<p>
-Parameter substitution / macro expansion.
-</p>
-</body>
-</html>
diff --git a/solr/build.gradle b/solr/core/src/java/org/apache/solr/search/facet/package-info.java
similarity index 86%
copy from solr/build.gradle
copy to solr/core/src/java/org/apache/solr/search/facet/package-info.java
index 9edc4d1..fbbb625 100644
--- a/solr/build.gradle
+++ b/solr/core/src/java/org/apache/solr/search/facet/package-info.java
@@ -15,8 +15,8 @@
  * limitations under the License.
  */
 
-description = 'Parent project for Apache Solr'
-
-subprojects {
-  group "org.apache.solr"
-}
\ No newline at end of file
+/**
+ * APIs and classes for the JSON Facet API.
+ * This is currently experimental!
+ */
+package org.apache.solr.search.facet;
diff --git a/solr/core/src/java/org/apache/solr/search/facet/package.html b/solr/core/src/java/org/apache/solr/search/facet/package.html
deleted file mode 100644
index a0590cb..0000000
--- a/solr/core/src/java/org/apache/solr/search/facet/package.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<!--
- 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.
--->
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-</head>
-<body>
-<p>
-APIs and classes for the JSON Facet API.
-This is currently experimental!
-</p>
-</body>
-</html>
diff --git a/solr/build.gradle b/solr/core/src/java/org/apache/solr/util/circuitbreaker/package-info.java
similarity index 87%
copy from solr/build.gradle
copy to solr/core/src/java/org/apache/solr/util/circuitbreaker/package-info.java
index 9edc4d1..75718b5 100644
--- a/solr/build.gradle
+++ b/solr/core/src/java/org/apache/solr/util/circuitbreaker/package-info.java
@@ -15,8 +15,7 @@
  * limitations under the License.
  */
 
-description = 'Parent project for Apache Solr'
-
-subprojects {
-  group "org.apache.solr"
-}
\ No newline at end of file
+/**
+ * Support for triggering exceptions on excessive resource usage
+ */
+package org.apache.solr.util.circuitbreaker;
\ No newline at end of file
diff --git a/solr/test-framework/build.gradle b/solr/test-framework/build.gradle
index 23d9050..ef6ad6b 100644
--- a/solr/test-framework/build.gradle
+++ b/solr/test-framework/build.gradle
@@ -32,3 +32,4 @@ dependencies {
   implementation 'com.lmax:disruptor'
   api 'org.awaitility:awaitility'
 }
+


[lucene-solr] 06/39: LUCENE-9474: Make the version number configurable from outside. This mainly allows Jenkins to set a different suffix than "SNAPSHOT"

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit c188e80b90da365972c8e19a246ab94417f6a5fa
Author: Uwe Schindler <us...@apache.org>
AuthorDate: Sun Aug 23 19:26:40 2020 +0200

    LUCENE-9474: Make the version number configurable from outside. This mainly allows Jenkins to set a different suffix than "SNAPSHOT"
---
 build.gradle | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/build.gradle b/build.gradle
index f145c73..571ab30 100644
--- a/build.gradle
+++ b/build.gradle
@@ -26,10 +26,24 @@ plugins {
   id "de.undercouch.download" version "4.0.2" apply false
 }
 
-// Project version.
-version = "9.0.0-SNAPSHOT"
+apply from: file('gradle/defaults.gradle')
 
 // General metadata.
+
+// Calculate project version:
+version = {
+  // Release manager: update base version here after release:
+  String baseVersion = '9.0.0'
+
+  // On a release explicitly set release version in one go:
+  //  -Dversion.release=x.y.z
+  
+  // Jenkins can just set just a suffix, overriding SNAPSHOT, e.g. using build id:
+  //  -Dversion.suffix=jenkins123
+  
+  String versionSuffix = propertyOrDefault('version.suffix', 'SNAPSHOT')
+  return propertyOrDefault('version.release', "${baseVersion}-${versionSuffix}")
+}()
 description = 'Grandparent project for Apache Lucene Core and Apache Solr'
 
 // Propagate version and derived properties across projects.
@@ -91,7 +105,6 @@ apply from: file('gradle/ant-compat/folder-layout.gradle')
 
 // Set up defaults and configure aspects for certain modules or functionality
 // (java, tests)
-apply from: file('gradle/defaults.gradle')
 apply from: file('gradle/defaults-java.gradle')
 apply from: file('gradle/testing/defaults-tests.gradle')
 apply from: file('gradle/testing/randomization.gradle')


[lucene-solr] 08/39: LUCENE-9435: Clean up ant compatability remnants in Gradle build

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 969c8ec597e455f1e007e0c776ff5d9959da44f2
Author: Dawid Weiss <da...@carrotsearch.com>
AuthorDate: Sun Aug 30 14:01:04 2020 +0200

    LUCENE-9435: Clean up ant compatability remnants in Gradle build
    
    * Removing ant-only unused tasks.
    * Correct message in TestVersion.java
    * Remove unused file.
    * Removing forbidden API rules for ant.
    * Remove 'resolve' emulation.
    * Move ecj-lint to task-definition-relative folder.
    * Remove 'packaging' specification. It'll have to wait until proper new packaging is implemented for Solr distribution.
    * Move render-javadoc tasks's files to task-relative location.
    * Moved security manager policies and default JDK logging file to gradle's task relative locations.
    * Removing obsolete ant tools. Moving check source patterns under gradle's folder.
    * Correct paths.
    * Correct property name in task selector.
---
 build.gradle                                       |   2 -
 .../ant-compat/forbidden-api-rules-in-sync.gradle  |  54 --
 gradle/ant-compat/jar-checks.gradle                |  26 -
 gradle/ant-compat/solr-forbidden-apis.gradle       |   2 +-
 gradle/documentation/render-javadoc.gradle         |  15 +-
 .../render-javadoc}/java11/package-list            |   0
 .../render-javadoc}/junit/package-list             |   0
 .../render-javadoc}/prettify/inject-javadocs.js    |   0
 .../render-javadoc}/prettify/prettify.css          |   0
 .../render-javadoc}/prettify/prettify.js           |   0
 .../render-javadoc}/table_padding.css              |   0
 gradle/testing/defaults-tests.gradle               |   2 +-
 .../testing/defaults-tests}/logging.properties     |   0
 .../testing/policies}/replicator-tests.policy      |   0
 .../testing/policies}/tests.policy                 |   0
 gradle/testing/randomization.gradle                |   4 +-
 gradle/validation/ecj-lint.gradle                  |   2 +-
 .../validation/ecj-lint}/ecj.javadocs.prefs        |   0
 gradle/validation/forbidden-apis.gradle            |   2 +-
 gradle/validation/validate-source-patterns.gradle  |   4 +-
 .../check-source-patterns.groovy                   |   0
 .../test/org/apache/lucene/util/TestVersion.java   |   2 +-
 lucene/tools/build.xml                             |  64 --
 lucene/tools/custom-tasks.xml                      | 149 ----
 lucene/tools/forbiddenApis/base.txt                |  64 --
 lucene/tools/forbiddenApis/lucene.txt              |  49 --
 lucene/tools/forbiddenApis/servlet-api.txt         |  43 -
 lucene/tools/forbiddenApis/solr.txt                |  61 --
 lucene/tools/forbiddenApis/tests.txt               |  29 -
 lucene/tools/ivy.xml                               |  29 -
 lucene/tools/junit4/cached-timehints.txt           |   0
 lucene/tools/src/groovy/check-working-copy.groovy  |  61 --
 .../src/groovy/install-markdown-filter.groovy      |  61 --
 lucene/tools/src/groovy/run-beaster.groovy         | 121 ---
 lucene/tools/src/groovy/run-maven-build.groovy     |  50 --
 lucene/tools/src/java/lucene-solr.antlib.xml       |  27 -
 .../dependencies/GetMavenDependenciesTask.java     | 920 ---------------------
 .../dependencies/InterpolatedProperties.java       | 162 ----
 .../lucene/validation/LibVersionsCheckTask.java    | 903 --------------------
 .../apache/lucene/validation/LicenseCheckTask.java | 352 --------
 .../org/apache/lucene/validation/LicenseType.java  |  75 --
 .../lucene/validation/ivyde/IvyNodeElement.java    | 178 ----
 .../validation/ivyde/IvyNodeElementAdapter.java    | 135 ---
 solr/contrib/prometheus-exporter/build.gradle      |   8 -
 44 files changed, 18 insertions(+), 3638 deletions(-)

diff --git a/build.gradle b/build.gradle
index ec5fed0..4c8209a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -163,12 +163,10 @@ apply from: file('gradle/help.gradle')
 // of potential problems with the build conventions, dependencies, etc.
 apply from: file('gradle/ant-compat/force-versions.gradle')
 apply from: file('gradle/ant-compat/misc.gradle')
-apply from: file('gradle/ant-compat/resolve.gradle')
 apply from: file('gradle/ant-compat/post-jar.gradle')
 apply from: file('gradle/ant-compat/test-classes-cross-deps.gradle')
 apply from: file('gradle/ant-compat/artifact-naming.gradle')
 apply from: file('gradle/ant-compat/solr-forbidden-apis.gradle')
-apply from: file('gradle/ant-compat/forbidden-api-rules-in-sync.gradle')
 
 apply from: file('gradle/documentation/documentation.gradle')
 apply from: file('gradle/documentation/changes-to-html.gradle')
diff --git a/gradle/ant-compat/forbidden-api-rules-in-sync.gradle b/gradle/ant-compat/forbidden-api-rules-in-sync.gradle
deleted file mode 100644
index c36847f..0000000
--- a/gradle/ant-compat/forbidden-api-rules-in-sync.gradle
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-// Just make sure the forbidden API rules are in sync between gradle and ant versions until
-// we get rid of ant build.
-
-def linesOf(FileTree ftree) {
-  return ftree.collectMany { path ->
-    path.readLines("UTF-8")
-      .collect { line -> line.trim() }
-      .findAll { line -> !line.startsWith("#") }
-      .unique()
-      .collect { line -> [path: path, line: line] }
-  }.groupBy { e -> e.line }
-}
-
-configure(rootProject) {
-  task verifyForbiddenApiRulesInSync() {
-    doFirst {
-      // Read all rules line by line from ant, gradle, remove comments, uniq.
-      // Rule sets should be identical.
-      def gradleRules = linesOf(fileTree("gradle/validation/forbidden-apis", { include "**/*.txt" }))
-      def antRules = linesOf(project(":lucene").fileTree("tools/forbiddenApis", { include "**/*.txt" }))
-
-      def antOnlyLines = antRules.keySet() - gradleRules.keySet()
-      def gradleOnlyLines = gradleRules.keySet() - antRules.keySet()
-
-      if (!gradleOnlyLines.isEmpty() || !antOnlyLines.isEmpty()) {
-        project.logger.log(LogLevel.ERROR, "The following rules don't have counterparts:\n" +
-          (gradleRules.findAll { gradleOnlyLines.contains(it.key) } + antRules.findAll { antOnlyLines.contains(it.key)})
-            .collectMany { it.value }
-            .join("\n"))
-        throw new GradleException("Forbidden APIs rules out of sync.")
-      }
-    }
-  }
-
-  check.dependsOn verifyForbiddenApiRulesInSync
-}
diff --git a/gradle/ant-compat/jar-checks.gradle b/gradle/ant-compat/jar-checks.gradle
deleted file mode 100644
index a93a002..0000000
--- a/gradle/ant-compat/jar-checks.gradle
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-// This file is not included but is kept in ant-compat so that cleanup can be done later
-
-// Remove special handling of dependency checksum validation/ collection for Solr where
-// transitive Lucene dependencies are sucked in to licenses/ folder. We can just copy
-// Lucene licenses as a whole (they're joint projects after all).
-//
-// the hack is in 'jar-checks.gradle' under:
-// def isSolr = project.path.startsWith(":solr")
diff --git a/gradle/ant-compat/solr-forbidden-apis.gradle b/gradle/ant-compat/solr-forbidden-apis.gradle
index e55c745..bb4dc60 100644
--- a/gradle/ant-compat/solr-forbidden-apis.gradle
+++ b/gradle/ant-compat/solr-forbidden-apis.gradle
@@ -19,7 +19,7 @@
 // Why does solr exclude these from forbidden API checks?
 
 configure(project(":solr:core")) {
-  configure([forbiddenApisMain, forbiddenApisTest]) {
+  tasks.matching { it.name == "forbiddenApisMain" || it.name == "forbiddenApisTest" }.all {
     exclude "org/apache/solr/internal/**"
     exclude "org/apache/hadoop/**"
   }
diff --git a/gradle/documentation/render-javadoc.gradle b/gradle/documentation/render-javadoc.gradle
index 27d282b..a7a76ef 100644
--- a/gradle/documentation/render-javadoc.gradle
+++ b/gradle/documentation/render-javadoc.gradle
@@ -65,8 +65,9 @@ allprojects {
 
 // Set up titles and link up some offline docs for all documentation
 // (they may be unused but this doesn't do any harm).
-def javaJavadocPackages = project.project(':lucene').file('tools/javadoc/java11/')
-def junitJavadocPackages = project.project(':lucene').file('tools/javadoc/junit/')
+def taskResources = "${rootProject.projectDir}/gradle/documentation/render-javadoc"
+def javaJavadocPackages = rootProject.file("${taskResources}/java11/")
+def junitJavadocPackages = rootProject.file("${taskResources}/junit/")
 allprojects {
   project.tasks.withType(RenderJavadocTask) {
     title = "${project.path.startsWith(':lucene') ? 'Lucene' : 'Solr'} ${project.version} ${project.name} API"
@@ -305,15 +306,19 @@ class RenderJavadocTask extends DefaultTask {
       throw new GradleException("Javadoc generation failed for ${project.path},\n  Options file at: ${optionsFile}\n  Command output at: ${outputFile}", cause)
     }
 
+    def taskResources = "${project.rootDir}/gradle/documentation/render-javadoc"
+
     // append some special table css, prettify css
     ant.concat(destfile: "${outputDir}/stylesheet.css", append: "true", fixlastline: "true", encoding: "UTF-8") {
-      filelist(dir: project.project(":lucene").file("tools/javadoc"), files: "table_padding.css")
-      filelist(dir: project.project(":lucene").file("tools/prettify"), files: "prettify.css")
+      filelist(dir: taskResources, files: "table_padding.css")
+      filelist(dir: project.file("${taskResources}/prettify"), files: "prettify.css")
     }
+
     // append prettify to scripts
     ant.concat(destfile: "${outputDir}/script.js", append: "true", fixlastline: "true", encoding: "UTF-8") {
-      filelist(dir: project.project(':lucene').file("tools/prettify"), files: "prettify.js inject-javadocs.js")
+      filelist(dir: project.file("${taskResources}/prettify"), files: "prettify.js inject-javadocs.js")
     }
+
     ant.fixcrlf(srcdir: outputDir, includes: "stylesheet.css script.js", eol: "lf", fixlast: "true", encoding: "UTF-8")
   }
 }
diff --git a/lucene/tools/javadoc/java11/package-list b/gradle/documentation/render-javadoc/java11/package-list
similarity index 100%
rename from lucene/tools/javadoc/java11/package-list
rename to gradle/documentation/render-javadoc/java11/package-list
diff --git a/lucene/tools/javadoc/junit/package-list b/gradle/documentation/render-javadoc/junit/package-list
similarity index 100%
rename from lucene/tools/javadoc/junit/package-list
rename to gradle/documentation/render-javadoc/junit/package-list
diff --git a/lucene/tools/prettify/inject-javadocs.js b/gradle/documentation/render-javadoc/prettify/inject-javadocs.js
similarity index 100%
rename from lucene/tools/prettify/inject-javadocs.js
rename to gradle/documentation/render-javadoc/prettify/inject-javadocs.js
diff --git a/lucene/tools/prettify/prettify.css b/gradle/documentation/render-javadoc/prettify/prettify.css
similarity index 100%
rename from lucene/tools/prettify/prettify.css
rename to gradle/documentation/render-javadoc/prettify/prettify.css
diff --git a/lucene/tools/prettify/prettify.js b/gradle/documentation/render-javadoc/prettify/prettify.js
similarity index 100%
rename from lucene/tools/prettify/prettify.js
rename to gradle/documentation/render-javadoc/prettify/prettify.js
diff --git a/lucene/tools/javadoc/table_padding.css b/gradle/documentation/render-javadoc/table_padding.css
similarity index 100%
rename from lucene/tools/javadoc/table_padding.css
rename to gradle/documentation/render-javadoc/table_padding.css
diff --git a/gradle/testing/defaults-tests.gradle b/gradle/testing/defaults-tests.gradle
index 9bca17b..c4316d5 100644
--- a/gradle/testing/defaults-tests.gradle
+++ b/gradle/testing/defaults-tests.gradle
@@ -72,7 +72,7 @@ allprojects {
 
       jvmArgs Commandline.translateCommandline(propertyOrDefault("tests.jvmargs", "-XX:TieredStopAtLevel=1 -XX:+UseParallelGC -XX:-UseBiasedLocking -DconfigurationFile=log4j2.xml -Dorg.apache.xml.dtm.DTMManager=org.apache.xml.dtm.ref.DTMManagerDefault"));
 
-      systemProperty 'java.util.logging.config.file', file("${commonDir}/tools/junit4/logging.properties")
+      systemProperty 'java.util.logging.config.file', rootProject.file("gradle/testing/defaults-tests/logging.properties")
       systemProperty 'java.awt.headless', 'true'
       systemProperty 'jdk.map.althashing.threshold', '0'
 
diff --git a/lucene/tools/junit4/logging.properties b/gradle/testing/defaults-tests/logging.properties
similarity index 100%
rename from lucene/tools/junit4/logging.properties
rename to gradle/testing/defaults-tests/logging.properties
diff --git a/lucene/tools/junit4/replicator-tests.policy b/gradle/testing/policies/replicator-tests.policy
similarity index 100%
rename from lucene/tools/junit4/replicator-tests.policy
rename to gradle/testing/policies/replicator-tests.policy
diff --git a/lucene/tools/junit4/tests.policy b/gradle/testing/policies/tests.policy
similarity index 100%
rename from lucene/tools/junit4/tests.policy
rename to gradle/testing/policies/tests.policy
diff --git a/gradle/testing/randomization.gradle b/gradle/testing/randomization.gradle
index f1d57d0..eb539c7 100644
--- a/gradle/testing/randomization.gradle
+++ b/gradle/testing/randomization.gradle
@@ -177,10 +177,10 @@ allprojects {
         if (Boolean.parseBoolean(testOptionsResolved["tests.useSecurityManager"])) {
           if (project.path == ":lucene:replicator") {
             systemProperty 'java.security.manager', "org.apache.lucene.util.TestSecurityManager"
-            systemProperty 'java.security.policy', rootProject.file("lucene/tools/junit4/replicator-tests.policy")
+            systemProperty 'java.security.policy', rootProject.file("gradle/testing/policies/replicator-tests.policy")
           } else if (project.path.startsWith(":lucene")) {
             systemProperty 'java.security.manager', "org.apache.lucene.util.TestSecurityManager"
-            systemProperty 'java.security.policy', rootProject.file("lucene/tools/junit4/tests.policy")
+            systemProperty 'java.security.policy', rootProject.file("gradle/testing/policies/tests.policy")
           } else {
             systemProperty 'common-solr.dir', commonSolrDir
             systemProperty 'java.security.manager', "org.apache.lucene.util.TestSecurityManager"
diff --git a/gradle/validation/ecj-lint.gradle b/gradle/validation/ecj-lint.gradle
index 5ae13c1..56bbd8d 100644
--- a/gradle/validation/ecj-lint.gradle
+++ b/gradle/validation/ecj-lint.gradle
@@ -69,7 +69,7 @@ allprojects {
         args += [ "-proc:none" ]
         args += [ "-nowarn" ]
         args += [ "-enableJavadoc" ]
-        args += [ "-properties", project(":lucene").file("tools/javadoc/ecj.javadocs.prefs").absolutePath ]
+        args += [ "-properties", rootProject.file("gradle/validation/ecj-lint/ecj.javadocs.prefs").absolutePath ]
 
         doFirst {
           tmpDst.mkdirs()
diff --git a/lucene/tools/javadoc/ecj.javadocs.prefs b/gradle/validation/ecj-lint/ecj.javadocs.prefs
similarity index 100%
rename from lucene/tools/javadoc/ecj.javadocs.prefs
rename to gradle/validation/ecj-lint/ecj.javadocs.prefs
diff --git a/gradle/validation/forbidden-apis.gradle b/gradle/validation/forbidden-apis.gradle
index 33c1d68..8fe5199 100644
--- a/gradle/validation/forbidden-apis.gradle
+++ b/gradle/validation/forbidden-apis.gradle
@@ -1,4 +1,4 @@
-/*
+  /*
  * 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.
diff --git a/gradle/validation/validate-source-patterns.gradle b/gradle/validation/validate-source-patterns.gradle
index 53630ed..ce27e2d 100644
--- a/gradle/validation/validate-source-patterns.gradle
+++ b/gradle/validation/validate-source-patterns.gradle
@@ -15,8 +15,6 @@
  * limitations under the License.
  */
 
-
-// Equivalent of ant's "validate-source-patterns".
 // This should be eventually rewritten in plain gradle. For now, delegate to
 // the ant/groovy script we already have.
 
@@ -37,7 +35,7 @@ configure(rootProject) {
           classname: "org.codehaus.groovy.ant.Groovy",
           classpath: configurations.checkSourceDeps.asPath)
 
-      ant.groovy(src: project(":lucene").file("tools/src/groovy/check-source-patterns.groovy"))
+      ant.groovy(src: rootProject.file("gradle/validation/validate-source-patterns/check-source-patterns.groovy"))
     }
   }
 }
\ No newline at end of file
diff --git a/lucene/tools/src/groovy/check-source-patterns.groovy b/gradle/validation/validate-source-patterns/check-source-patterns.groovy
similarity index 100%
rename from lucene/tools/src/groovy/check-source-patterns.groovy
rename to gradle/validation/validate-source-patterns/check-source-patterns.groovy
diff --git a/lucene/core/src/test/org/apache/lucene/util/TestVersion.java b/lucene/core/src/test/org/apache/lucene/util/TestVersion.java
index e19c615..36cb1a5 100644
--- a/lucene/core/src/test/org/apache/lucene/util/TestVersion.java
+++ b/lucene/core/src/test/org/apache/lucene/util/TestVersion.java
@@ -192,7 +192,7 @@ public class TestVersion extends LuceneTestCase {
     String commonBuildVersion = System.getProperty("tests.LUCENE_VERSION");
     assumeTrue("Null 'tests.LUCENE_VERSION' test property. You should run the tests with the official Lucene build file",
         commonBuildVersion != null);
-    assertEquals("Version.LATEST does not match the one given in common-build.xml",
+    assertEquals("Version.LATEST does not match the one given in tests.LUCENE_VERSION property",
         Version.LATEST.toString(), commonBuildVersion);
   }
 
diff --git a/lucene/tools/build.xml b/lucene/tools/build.xml
deleted file mode 100644
index b245dce..0000000
--- a/lucene/tools/build.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
- 
-        http://www.apache.org/licenses/LICENSE-2.0
- 
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-
-<project name="tools" default="default">
-  <description>Lucene Tools</description>
-
-  <property name="build.dir" location="../build/tools"/>
-  
-  <property name="rat.additional-includes" value="forbiddenApis/**,prettify/**"/>
-
-  <import file="../common-build.xml"/>
-
-  <path id="classpath">
-    <!-- TODO: we need this for forbidden-apis to be happy, because it does not support "includeantruntime": -->
-    <fileset dir="lib"/>
-  </path>
-
-  <path id="test.classpath"/>
-
-  <!-- redefine the test compilation, -test and -check-totals, so these are just no-ops -->
-  <target name="compile-test"/>
-  <target name="-test"/>
-  <target name="-check-totals"/>
-  
-  <!-- redefine the forbidden apis to be no-ops -->
-  <target name="-check-forbidden-tests"/>
-  <target name="-check-forbidden-sysout"/>
-
-  <!-- disable clover -->
-  <target name="-clover.setup" if="run.clover"/>
-
-  <!--  
-      Specialize compile-core to not depend on clover, to exclude a 
-      classpath reference when compiling, and to not attempt to copy
-      non-existent resource files to the build output directory.
-   -->
-  <target name="compile-core" depends="init" description="Compiles tools classes.">
-    <compile srcdir="${src.dir}" destdir="${build.dir}/classes/java" includeantruntime="true">
-      <classpath refid="classpath"/>
-    </compile>
-    <copy todir="${build.dir}/classes/java">
-      <fileset dir="${src.dir}" excludes="**/*.java" />
-    </copy>
-  </target>
-
-  <target name="javadocs"/> <!-- to make common-build.xml happy -->
-  <target name="pitest"/> <!-- to make common-build.xml happy -->
-</project>
diff --git a/lucene/tools/custom-tasks.xml b/lucene/tools/custom-tasks.xml
deleted file mode 100644
index 4b5c3ea..0000000
--- a/lucene/tools/custom-tasks.xml
+++ /dev/null
@@ -1,149 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.
--->
-<project name="custom-tasks">
-  <description>
-    This file is designed for importing into a main build file, and not intended
-    for standalone use.
-  </description>
-
-  <target name="load-custom-tasks" unless="custom-tasks.loaded">
-    <dirname file="${ant.file.custom-tasks}" property="custom-tasks.dir"/>
-    <taskdef resource="lucene-solr.antlib.xml">
-      <classpath>
-        <pathelement location="${custom-tasks.dir}/../build/tools/classes/java" />
-      </classpath>
-    </taskdef>
-    <property name="custom-tasks.loaded" value="true"/>
-  </target>
-
-  <filtermapper id="license-mapper-defaults">
-    <!-- Normalize input paths. -->
-    <replacestring from="\" to="/" />
-    <replaceregex pattern="\.jar$" replace="" flags="gi" />
-    
-    <!-- Some typical snapshot/minimalized JAR suffixes. -->
-    <replaceregex pattern="-min$" replace="" flags="gi" />
-    <replaceregex pattern="SNAPSHOT" replace="" flags="gi" />
-
-    <!-- Typical version patterns. -->
-    <replaceregex pattern="\.rc[0-9]+" replace="" flags="gi" />
-    <replaceregex pattern="(?&lt;!log4j)\-(r)?([0-9\-\_\.])+(([a-zA-Z]+)([0-9\-\.])*)?" replace="" flags="gi" />
-    
-    <replaceregex pattern="[-]tests$" replace="-tests" flags="gi" />
-
-    <!-- git hashcode pattern: it's always 40 chars right? -->
-    <replaceregex pattern="\-[a-z0-9]{40,40}$" replace="" flags="gi" />
-  </filtermapper>
-
-  <macrodef name="license-check-macro">
-    <attribute name="dir" />
-    <attribute name="licensedir" />
-    <element name="additional-excludes" optional="true" />
-    <element name="additional-filters"  optional="true" />
-    <sequential>
-      <!-- LICENSE and NOTICE verification macro. -->
-      <echo>License check under: @{dir}</echo>
-      <licenses licenseDirectory="@{licensedir}" skipChecksum="${skipChecksum}" skipRegexChecksum="${skipRegexChecksum}" skipSnapshotsChecksum="${skipSnapshotsChecksum}">
-        <fileset dir="@{dir}">
-          <include name="**/*.jar" />
-          <!-- Speed up scanning a bit. -->
-          <exclude name="**/.git/**" />
-          <exclude name="**/.svn/**" />
-          <exclude name="**/bin/**" />
-          <exclude name="**/build/**" />
-          <exclude name="**/dist/**" />
-          <exclude name="**/src/**" />
-          <additional-excludes />
-        </fileset>
-
-        <licenseMapper>
-          <chainedmapper>
-            <filtermapper refid="license-mapper-defaults"/>
-            <filtermapper>
-              <!-- Non-typical version patterns. -->
-              <additional-filters />
-            </filtermapper>
-          </chainedmapper>
-        </licenseMapper>
-      </licenses>
-    </sequential>
-  </macrodef>
-
-  <macrodef name="lib-versions-check-macro">
-    <attribute name="dir"/>
-    <attribute name="centralized.versions.file"/>
-    <attribute name="top.level.ivy.settings.file"/>
-    <attribute name="ivy.resolution-cache.dir"/>
-    <attribute name="ivy.lock-strategy"/>
-    <attribute name="common.build.dir"/>
-    <attribute name="ignore.conflicts.file"/>
-    <sequential>
-      <!-- 
-        Verify that the '/org/name' keys in ivy-versions.properties are sorted
-        lexically and are neither duplicates nor orphans, and that all
-         dependencies in all ivy.xml files use rev="${/org/name}" format.
-        -->
-      <echo>Lib versions check under: @{dir}</echo>
-      <libversions centralizedVersionsFile="@{centralized.versions.file}"
-                   topLevelIvySettingsFile="@{top.level.ivy.settings.file}"
-                   ivyResolutionCacheDir="@{ivy.resolution-cache.dir}"
-                   ivyLockStrategy="@{ivy.lock-strategy}"
-                   commonBuildDir="@{common.build.dir}"
-                   ignoreConflictsFile="@{ignore.conflicts.file}">
-        <fileset dir="@{dir}">
-          <include name="**/ivy.xml" />
-          <!-- Speed up scanning a bit. -->
-          <exclude name="**/.git/**" />
-          <exclude name="**/.svn/**" />
-          <exclude name="**/bin/**" />
-          <exclude name="**/build/**" />
-          <exclude name="**/dist/**" />
-          <exclude name="**/src/**" />
-        </fileset>
-      </libversions>
-    </sequential>
-  </macrodef>
-
-  <macrodef name="get-maven-dependencies-macro">
-    <attribute name="dir"/>
-    <attribute name="centralized.versions.file"/>
-    <attribute name="module.dependencies.properties.file"/>
-    <attribute name="maven.dependencies.filters.file"/>
-    <sequential>
-      <echo>Get maven dependencies called under: @{dir}</echo>
-      <mvndeps centralizedVersionsFile="@{centralized.versions.file}"
-               moduleDependenciesPropertiesFile="@{module.dependencies.properties.file}"
-               mavenDependenciesFiltersFile="@{maven.dependencies.filters.file}">
-        <fileset dir="@{dir}">
-          <include name="**/ivy.xml" />
-          <!-- Speed up scanning a bit. -->
-          <exclude name="**/.git/**" />
-          <exclude name="**/.svn/**" />
-          <exclude name="**/bin/**" />
-          <exclude name="**/build/**" />
-          <exclude name="**/dist/**" />
-          <exclude name="**/src/**" />
-          <exclude name="**/maven-build/**" />
-          <exclude name="**/idea-build/**" />
-          <exclude name="**/dev-tools/**" />
-        </fileset>
-      </mvndeps>
-    </sequential>
-  </macrodef>
-</project>
diff --git a/lucene/tools/forbiddenApis/base.txt b/lucene/tools/forbiddenApis/base.txt
deleted file mode 100644
index 6ff080b..0000000
--- a/lucene/tools/forbiddenApis/base.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-#  Licensed to the Apache Software Foundation (ASF) under one or more
-#  contributor license agreements.  See the NOTICE file distributed with
-#  this work for additional information regarding copyright ownership.
-#  The ASF licenses this file to You under the Apache License, Version 2.0
-#  (the "License"); you may not use this file except in compliance with
-#  the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-@defaultMessage Spawns threads with vague names; use a custom thread factory (Lucene's NamedThreadFactory, Solr's SolrNamedThreadFactory) and name threads so that you can tell (by its name) which executor it is associated with
-java.util.concurrent.Executors#newFixedThreadPool(int)
-java.util.concurrent.Executors#newSingleThreadExecutor()
-java.util.concurrent.Executors#newCachedThreadPool()
-java.util.concurrent.Executors#newSingleThreadScheduledExecutor()
-java.util.concurrent.Executors#newScheduledThreadPool(int)
-java.util.concurrent.Executors#defaultThreadFactory()
-java.util.concurrent.Executors#privilegedThreadFactory()
-
-@defaultMessage Properties files should be read/written with Reader/Writer, using UTF-8 charset. This allows reading older files with unicode escapes, too.
-java.util.Properties#load(java.io.InputStream)
-java.util.Properties#save(java.io.OutputStream,java.lang.String)
-java.util.Properties#store(java.io.OutputStream,java.lang.String)
-
-@defaultMessage The context classloader should never be used for resource lookups, unless there is a 3rd party library that needs it. Always pass a classloader down as method parameters.
-java.lang.Thread#getContextClassLoader()
-java.lang.Thread#setContextClassLoader(java.lang.ClassLoader)
-
-java.lang.Character#codePointBefore(char[],int) @ Implicit start offset is error-prone when the char[] is a buffer and the first chars are random chars
-java.lang.Character#codePointAt(char[],int) @ Implicit end offset is error-prone when the char[] is a buffer and the last chars are random chars
-
-java.io.File#delete() @ use Files.delete for real exception, IOUtils.deleteFilesIgnoringExceptions if you dont care
-
-java.util.Collections#shuffle(java.util.List) @ Use shuffle(List, Random) instead so that it can be reproduced
-
-java.util.Locale#forLanguageTag(java.lang.String) @ use new Locale.Builder().setLanguageTag(...).build() which has error handling
-java.util.Locale#toString() @ use Locale#toLanguageTag() for a standardized BCP47 locale name
-
-@defaultMessage Constructors for wrapper classes of Java primitives should be avoided in favor of the public static methods available or autoboxing
-java.lang.Integer#<init>(int)
-java.lang.Integer#<init>(java.lang.String)
-java.lang.Byte#<init>(byte)
-java.lang.Byte#<init>(java.lang.String)
-java.lang.Short#<init>(short)
-java.lang.Short#<init>(java.lang.String)
-java.lang.Long#<init>(long)
-java.lang.Long#<init>(java.lang.String)
-java.lang.Boolean#<init>(boolean)
-java.lang.Boolean#<init>(java.lang.String)
-java.lang.Character#<init>(char)
-java.lang.Float#<init>(float)
-java.lang.Float#<init>(double)
-java.lang.Float#<init>(java.lang.String)
-java.lang.Double#<init>(double)
-java.lang.Double#<init>(java.lang.String)
-
-@defaultMessage Java deserialization is unsafe when the data is untrusted. The java developer is powerless: no checks or casts help, exploitation can happen in places such as clinit or finalize!
-java.io.ObjectInputStream
-java.io.ObjectOutputStream
diff --git a/lucene/tools/forbiddenApis/lucene.txt b/lucene/tools/forbiddenApis/lucene.txt
deleted file mode 100644
index 0cc4edd..0000000
--- a/lucene/tools/forbiddenApis/lucene.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-#  Licensed to the Apache Software Foundation (ASF) under one or more
-#  contributor license agreements.  See the NOTICE file distributed with
-#  this work for additional information regarding copyright ownership.
-#  The ASF licenses this file to You under the Apache License, Version 2.0
-#  (the "License"); you may not use this file except in compliance with
-#  the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-@defaultMessage Use NIO.2 instead
-java.io.File
-java.io.FileInputStream
-java.io.FileOutputStream
-java.io.PrintStream#<init>(java.lang.String,java.lang.String)
-java.io.PrintWriter#<init>(java.lang.String,java.lang.String)
-java.util.Formatter#<init>(java.lang.String,java.lang.String,java.util.Locale)
-java.io.RandomAccessFile
-java.nio.file.Path#toFile()
-java.util.jar.JarFile
-java.util.zip.ZipFile
-@defaultMessage Prefer using ArrayUtil as Arrays#copyOfRange fills zeros for bad bounds
-java.util.Arrays#copyOfRange(byte[],int,int)
-java.util.Arrays#copyOfRange(char[],int,int)
-java.util.Arrays#copyOfRange(short[],int,int)
-java.util.Arrays#copyOfRange(int[],int,int)
-java.util.Arrays#copyOfRange(long[],int,int)
-java.util.Arrays#copyOfRange(float[],int,int)
-java.util.Arrays#copyOfRange(double[],int,int)
-java.util.Arrays#copyOfRange(boolean[],int,int)
-java.util.Arrays#copyOfRange(java.lang.Object[],int,int)
-java.util.Arrays#copyOfRange(java.lang.Object[],int,int,java.lang.Class)
-
-@defaultMessage Prefer using ArrayUtil as Arrays#copyOf fills zeros for bad bounds
-java.util.Arrays#copyOf(byte[],int)
-java.util.Arrays#copyOf(char[],int)
-java.util.Arrays#copyOf(short[],int)
-java.util.Arrays#copyOf(int[],int)
-java.util.Arrays#copyOf(long[],int)
-java.util.Arrays#copyOf(float[],int)
-java.util.Arrays#copyOf(double[],int)
-java.util.Arrays#copyOf(boolean[],int)
-java.util.Arrays#copyOf(java.lang.Object[],int)
-java.util.Arrays#copyOf(java.lang.Object[],int,java.lang.Class)
diff --git a/lucene/tools/forbiddenApis/servlet-api.txt b/lucene/tools/forbiddenApis/servlet-api.txt
deleted file mode 100644
index dc82e8f..0000000
--- a/lucene/tools/forbiddenApis/servlet-api.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-#  Licensed to the Apache Software Foundation (ASF) under one or more
-#  contributor license agreements.  See the NOTICE file distributed with
-#  this work for additional information regarding copyright ownership.
-#  The ASF licenses this file to You under the Apache License, Version 2.0
-#  (the "License"); you may not use this file except in compliance with
-#  the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-@defaultMessage Servlet API method is parsing request parameters without using the correct encoding if no extra configuration is given in the servlet container
-
-javax.servlet.ServletRequest#getParameter(java.lang.String) 
-javax.servlet.ServletRequest#getParameterMap() 
-javax.servlet.ServletRequest#getParameterNames() 
-javax.servlet.ServletRequest#getParameterValues(java.lang.String) 
-
-javax.servlet.http.HttpServletRequest#getSession() @ Servlet API getter has side effect of creating sessions
-
-@defaultMessage Servlet API method is broken and slow in some environments (e.g., Jetty's UTF-8 readers)
-
-javax.servlet.ServletRequest#getReader()
-javax.servlet.ServletResponse#getWriter()
-javax.servlet.ServletInputStream#readLine(byte[],int,int) 
-javax.servlet.ServletOutputStream#print(boolean)
-javax.servlet.ServletOutputStream#print(char)
-javax.servlet.ServletOutputStream#print(double)
-javax.servlet.ServletOutputStream#print(float)
-javax.servlet.ServletOutputStream#print(int)
-javax.servlet.ServletOutputStream#print(long)
-javax.servlet.ServletOutputStream#print(java.lang.String)
-javax.servlet.ServletOutputStream#println(boolean)
-javax.servlet.ServletOutputStream#println(char)
-javax.servlet.ServletOutputStream#println(double)
-javax.servlet.ServletOutputStream#println(float)
-javax.servlet.ServletOutputStream#println(int)
-javax.servlet.ServletOutputStream#println(long)
-javax.servlet.ServletOutputStream#println(java.lang.String)
diff --git a/lucene/tools/forbiddenApis/solr.txt b/lucene/tools/forbiddenApis/solr.txt
deleted file mode 100644
index bb177be..0000000
--- a/lucene/tools/forbiddenApis/solr.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-#  Licensed to the Apache Software Foundation (ASF) under one or more
-#  contributor license agreements.  See the NOTICE file distributed with
-#  this work for additional information regarding copyright ownership.
-#  The ASF licenses this file to You under the Apache License, Version 2.0
-#  (the "License"); you may not use this file except in compliance with
-#  the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-@defaultMessage Spawns threads without MDC logging context; use ExecutorUtil.newMDCAwareFixedThreadPool instead
-java.util.concurrent.Executors#newFixedThreadPool(int,java.util.concurrent.ThreadFactory)
-
-@defaultMessage Spawns threads without MDC logging context; use ExecutorUtil.newMDCAwareSingleThreadExecutor instead
-java.util.concurrent.Executors#newSingleThreadExecutor(java.util.concurrent.ThreadFactory)
-
-@defaultMessage Spawns threads without MDC logging context; use ExecutorUtil.newMDCAwareCachedThreadPool instead
-java.util.concurrent.Executors#newCachedThreadPool(java.util.concurrent.ThreadFactory)
-
-@defaultMessage Use ExecutorUtil.MDCAwareThreadPoolExecutor instead of ThreadPoolExecutor
-java.util.concurrent.ThreadPoolExecutor#<init>(int,int,long,java.util.concurrent.TimeUnit,java.util.concurrent.BlockingQueue,java.util.concurrent.ThreadFactory,java.util.concurrent.RejectedExecutionHandler)
-java.util.concurrent.ThreadPoolExecutor#<init>(int,int,long,java.util.concurrent.TimeUnit,java.util.concurrent.BlockingQueue)
-java.util.concurrent.ThreadPoolExecutor#<init>(int,int,long,java.util.concurrent.TimeUnit,java.util.concurrent.BlockingQueue,java.util.concurrent.ThreadFactory)
-java.util.concurrent.ThreadPoolExecutor#<init>(int,int,long,java.util.concurrent.TimeUnit,java.util.concurrent.BlockingQueue,java.util.concurrent.RejectedExecutionHandler)
-
-@defaultMessage Use slf4j classes instead
-org.apache.log4j.**
-org.apache.logging.log4j.**
-java.util.logging.**
-
-@defaultMessage Use RTimer/TimeOut/System.nanoTime for time comparisons, and `new Date()` output/debugging/stats of timestamps. If for some miscellaneous reason, you absolutely need to use this, use a SuppressForbidden.
-java.lang.System#currentTimeMillis()
-
-@defaultMessage Use corresponding Java 8 functional/streaming interfaces
-com.google.common.base.Function
-com.google.common.base.Joiner
-com.google.common.base.Predicate
-com.google.common.base.Supplier
-
-@defaultMessage Use java.nio.charset.StandardCharsets instead
-com.google.common.base.Charsets
-org.apache.commons.codec.Charsets
-
-@defaultMessage Use methods in java.util.Objects instead
-com.google.common.base.Objects#equal(java.lang.Object,java.lang.Object)
-com.google.common.base.Objects#hashCode(java.lang.Object[])
-com.google.common.base.Preconditions#checkNotNull(java.lang.Object)
-com.google.common.base.Preconditions#checkNotNull(java.lang.Object,java.lang.Object)
-
-@defaultMessage Use methods in java.util.Comparator instead
-com.google.common.collect.Ordering
-
-@defaultMessage Use org.apache.solr.common.annotation.JsonProperty  instead
-com.fasterxml.jackson.annotation.JsonProperty
-
-
diff --git a/lucene/tools/forbiddenApis/tests.txt b/lucene/tools/forbiddenApis/tests.txt
deleted file mode 100644
index fbcc0dd..0000000
--- a/lucene/tools/forbiddenApis/tests.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-#  Licensed to the Apache Software Foundation (ASF) under one or more
-#  contributor license agreements.  See the NOTICE file distributed with
-#  this work for additional information regarding copyright ownership.
-#  The ASF licenses this file to You under the Apache License, Version 2.0
-#  (the "License"); you may not use this file except in compliance with
-#  the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-junit.framework.TestCase @ All classes should derive from LuceneTestCase
-
-java.util.Random#<init>() @ Use RandomizedRunner's random() instead
-java.lang.Math#random() @ Use RandomizedRunner's random().nextDouble() instead
-
-# TODO: fix tests that do this!
-#java.lang.System#currentTimeMillis() @ Don't depend on wall clock times
-#java.lang.System#nanoTime() @ Don't depend on wall clock times
-
-com.carrotsearch.randomizedtesting.annotations.Seed @ Don't commit hardcoded seeds
-
-@defaultMessage Use LuceneTestCase.collate instead, which can avoid JDK-8071862
-java.text.Collator#compare(java.lang.Object,java.lang.Object)
-java.text.Collator#compare(java.lang.String,java.lang.String)
diff --git a/lucene/tools/ivy.xml b/lucene/tools/ivy.xml
deleted file mode 100644
index 1fa2974..0000000
--- a/lucene/tools/ivy.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.    
--->
-<ivy-module version="2.0">
-  <info organisation="org.apache.lucene" module="tools"/>
-  <configurations defaultconfmapping="compile->master">
-    <conf name="compile" transitive="false"/>
-  </configurations>
-  <dependencies>
-    <dependency org="org.apache.ant" name="ant" rev="${/org.apache.ant/ant}" conf="compile"/>
-    <dependency org="org.apache.ivy" name="ivy" rev="${/org.apache.ivy/ivy}" conf="compile"/>
-    <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/>
-  </dependencies>
-</ivy-module>
diff --git a/lucene/tools/junit4/cached-timehints.txt b/lucene/tools/junit4/cached-timehints.txt
deleted file mode 100644
index e69de29..0000000
diff --git a/lucene/tools/src/groovy/check-working-copy.groovy b/lucene/tools/src/groovy/check-working-copy.groovy
deleted file mode 100644
index 079a18b..0000000
--- a/lucene/tools/src/groovy/check-working-copy.groovy
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/** Task script that is called by Ant's build.xml file:
- * Checks GIT working copy for unversioned or modified files.
- */
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.Status;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
-import org.eclipse.jgit.errors.*;
-
-def setProjectPropertyFromSet = { prop, set ->
-  if (set) {
-    properties[prop] = '* ' + set.join(properties['line.separator'] + '* ');
-  }
-};
-
-try {
-  task.log('Initializing working copy...', Project.MSG_INFO);
-  final Repository repository = new FileRepositoryBuilder()
-    .setWorkTree(project.getBaseDir())
-    .setMustExist(true)
-    .build();
-
-  task.log('Checking working copy status...', Project.MSG_INFO);
-  final Status status = new Git(repository).status().call();
-  if (!status.isClean()) {
-    final SortedSet unversioned = new TreeSet(), modified = new TreeSet();
-    status.properties.each{ prop, val ->
-      if (val instanceof Set) {
-        if (prop in ['untracked', 'untrackedFolders', 'missing']) {
-          unversioned.addAll(val);
-        } else if (prop != 'ignoredNotInIndex') {
-          modified.addAll(val);
-        }
-      }
-    };
-    setProjectPropertyFromSet('wc.unversioned.files', unversioned);
-    setProjectPropertyFromSet('wc.modified.files', modified);
-  }
-} catch (RepositoryNotFoundException | NoWorkTreeException | NotSupportedException e) {
-  task.log('WARNING: Development directory is not a valid GIT checkout! Disabling checks...', Project.MSG_WARN);
-}
diff --git a/lucene/tools/src/groovy/install-markdown-filter.groovy b/lucene/tools/src/groovy/install-markdown-filter.groovy
deleted file mode 100644
index bd5ceb3..0000000
--- a/lucene/tools/src/groovy/install-markdown-filter.groovy
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/** Task script that is called by Ant's common-build.xml file:
- * Installs markdown filter into Ant.
- */
-
-import org.apache.tools.ant.AntTypeDefinition;
-import org.apache.tools.ant.ComponentHelper;
-import org.apache.tools.ant.filters.TokenFilter.ChainableReaderFilter;
-import com.vladsch.flexmark.util.ast.Document;
-import com.vladsch.flexmark.ast.Heading;
-import com.vladsch.flexmark.html.HtmlRenderer;
-import com.vladsch.flexmark.parser.Parser;
-import com.vladsch.flexmark.parser.ParserEmulationProfile;
-import com.vladsch.flexmark.util.html.Escaping;
-import com.vladsch.flexmark.util.options.MutableDataSet;
-import com.vladsch.flexmark.ext.abbreviation.AbbreviationExtension;
-import com.vladsch.flexmark.ext.autolink.AutolinkExtension;
-
-public final class MarkdownFilter extends ChainableReaderFilter {
-  @Override
-  public String filter(String markdownSource) {
-    MutableDataSet options = new MutableDataSet();
-    options.setFrom(ParserEmulationProfile.MARKDOWN);
-    options.set(Parser.EXTENSIONS, [ AbbreviationExtension.create(), AutolinkExtension.create() ]);
-    options.set(HtmlRenderer.RENDER_HEADER_ID, true);
-    options.set(HtmlRenderer.MAX_TRAILING_BLANK_LINES, 0);
-    Document parsed = Parser.builder(options).build().parse(markdownSource);
-
-    StringBuilder html = new StringBuilder('<html>\n<head>\n');
-    CharSequence title = parsed.getFirstChildAny(Heading.class)?.getText();          
-    if (title != null) {
-      html.append('<title>').append(Escaping.escapeHtml(title, false)).append('</title>\n');
-    }
-    html.append('<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\n')
-      .append('</head>\n<body>\n');
-    HtmlRenderer.builder(options).build().render(parsed, html);
-    html.append('</body>\n</html>\n');
-    return html;
-  }
-}
-
-AntTypeDefinition t = new AntTypeDefinition();
-t.setName('markdownfilter');
-t.setClass(MarkdownFilter.class);
-ComponentHelper.getComponentHelper(project).addDataTypeDefinition(t);
diff --git a/lucene/tools/src/groovy/run-beaster.groovy b/lucene/tools/src/groovy/run-beaster.groovy
deleted file mode 100644
index 057c147..0000000
--- a/lucene/tools/src/groovy/run-beaster.groovy
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/** Task script that is called by Ant's common-build.xml file:
- * Runs test beaster.
- */
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.BuildLogger;
-import org.apache.tools.ant.Project;
-
-
-static boolean logFailOutput(Object task, String outdir) {
-  def logFile = new File(outdir, "tests-failures.txt");
-  if (logFile.exists()) {
-    logFile.eachLine("UTF-8", { line ->
-      task.log(line, Project.MSG_ERR);
-    });
-  }
-}
-
-int iters = (properties['beast.iters'] ?: '1') as int;
-if (iters <= 1) {
-  throw new BuildException("Please give -Dbeast.iters with an int value > 1.");
-}
-
-def antcall = project.createTask('antcallback');
-
-def junitOutDir = properties["junit.output.dir"];
-
-def failed = false;
-
-(1..iters).each { i ->
-
-  def outdir = junitOutDir + "/" + i;
-  task.log('Beast round ' + i + " results: " + outdir, Project.MSG_INFO);
-  
-  try {
-    // disable verbose build logging:
-    project.buildListeners.each { listener ->
-      if (listener instanceof BuildLogger) {
-        listener.messageOutputLevel = Project.MSG_WARN;
-      }
-    };
-    
-    new File(outdir).mkdirs();
-    
-    properties["junit.output.dir"] = outdir;
-    
-    antcall.setReturn("tests.failed");
-    antcall.setTarget("-test");
-    antcall.setInheritAll(true);
-    antcall.setInheritRefs(true);
-    
-    antcall.with {
-
-      createParam().with {
-        name = "tests.isbeasting";
-        value = "true";
-      };
-      createParam().with {
-        name = "tests.timeoutSuite";
-        value = "900000";
-      };
-      createParam().with {
-        name = "junit.output.dir";
-        value = outdir;
-      };
-
-    };
-    
-    properties["junit.output.dir"] = outdir;
-
-    antcall.execute();
-
-    def antcallResult = project.properties.'tests.failed' as boolean;
-
-    if (antcallResult) {
-      failed = true;
-      logFailOutput(task, outdir)
-    }
-    
-  } catch (BuildException be) {
-    task.log(be.getMessage(), Project.MSG_ERR);
-    logFailOutput(task, outdir)
-    throw be;
-  } finally {
-    // restore build logging (unfortunately there is no way to get the original logging level (write-only property):
-    project.buildListeners.each { listener ->
-      if (listener instanceof BuildLogger) {
-        listener.messageOutputLevel = Project.MSG_INFO;
-      }
-    };
-  }
-};
-
-// restore junit output dir
-properties["junit.output.dir"] = junitOutDir;
-
-
-if (failed) {
-  task.log('Beasting finished with failure.', Project.MSG_INFO);
-  throw new BuildException("Beasting Failed!");
-} else {
-  task.log('Beasting finished Successfully.', Project.MSG_INFO);
-}
-
diff --git a/lucene/tools/src/groovy/run-maven-build.groovy b/lucene/tools/src/groovy/run-maven-build.groovy
deleted file mode 100644
index e241837..0000000
--- a/lucene/tools/src/groovy/run-maven-build.groovy
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/** Task script that is called by Ant's build.xml file:
- * Runs maven build from within Ant after creating POMs.
- */
-
-import groovy.xml.NamespaceBuilder;
-import org.apache.tools.ant.Project;
-
-def userHome = properties['user.home'], commonDir = properties['common.dir'];
-def propPrefix = '-mvn.inject.'; int propPrefixLen = propPrefix.length();
-
-def subProject = project.createSubProject();
-project.copyUserProperties(subProject);
-subProject.initProperties();
-new AntBuilder(subProject).sequential{
-  property(file: userHome+'/lucene.build.properties', prefix: propPrefix);
-  property(file: userHome+'/build.properties', prefix: propPrefix);
-  property(file: commonDir+'/build.properties', prefix: propPrefix);
-};
-
-def cmdlineProps = subProject.properties
-  .findAll{ k, v -> k.startsWith(propPrefix) }
-  .collectEntries{ k, v -> [k.substring(propPrefixLen), v] };
-cmdlineProps << project.userProperties.findAll{ k, v -> !k.startsWith('ant.') };
-
-def artifact = NamespaceBuilder.newInstance(ant, 'antlib:org.apache.maven.artifact.ant');
-
-task.log('Running Maven with props: ' + cmdlineProps.toString(), Project.MSG_INFO);
-artifact.mvn(pom: properties['maven-build-dir']+'/pom.xml', mavenVersion: properties['maven-version'], failonerror: true, fork: true) {
-  sysproperty(key: 'maven.multiModuleProjectDirectory', file: properties['maven-build-dir'])
-  cmdlineProps.each{ k, v -> arg(value: '-D' + k + '=' + v) };
-  arg(value: '-fae');
-  arg(value: 'install');
-};
diff --git a/lucene/tools/src/java/lucene-solr.antlib.xml b/lucene/tools/src/java/lucene-solr.antlib.xml
deleted file mode 100644
index 94a102d..0000000
--- a/lucene/tools/src/java/lucene-solr.antlib.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- -->
-<antlib>
-    <taskdef 
-        name="licenses" 
-        classname="org.apache.lucene.validation.LicenseCheckTask" />
-    <taskdef
-        name="libversions"
-        classname="org.apache.lucene.validation.LibVersionsCheckTask" />
-    <taskdef
-        name="mvndeps"
-        classname="org.apache.lucene.dependencies.GetMavenDependenciesTask" />
-</antlib> 
diff --git a/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java b/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java
deleted file mode 100644
index 570016c..0000000
--- a/lucene/tools/src/java/org/apache/lucene/dependencies/GetMavenDependenciesTask.java
+++ /dev/null
@@ -1,920 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.dependencies;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.ResourceCollection;
-import org.apache.tools.ant.types.resources.FileResource;
-import org.apache.tools.ant.types.resources.Resources;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.Reader;
-import java.io.Writer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.function.Consumer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-
-/**
- * An Ant task to generate a properties file containing maven dependency
- * declarations, used to filter the maven POMs when copying them to
- * maven-build/ via 'ant get-maven-poms', or to lucene/build/poms/
- * via the '-filter-maven-poms' target, which is called from the
- * 'generate-maven-artifacts' target.
- */
-public class GetMavenDependenciesTask extends Task {
-  private static final Pattern PROPERTY_PREFIX_FROM_IVY_XML_FILE_PATTERN = Pattern.compile
-      ("[/\\\\](lucene|solr)[/\\\\](?:(?:contrib|(analysis)|(example)|(server))[/\\\\])?([^/\\\\]+)[/\\\\]ivy\\.xml");
-  private static final Pattern COORDINATE_KEY_PATTERN = Pattern.compile("/([^/]+)/([^/]+)");
-  private static final Pattern MODULE_DEPENDENCIES_COORDINATE_KEY_PATTERN
-      = Pattern.compile("(.*?)(\\.test)?\\.dependencies");
-  // lucene/build/core/classes/java
-  private static final Pattern COMPILATION_OUTPUT_DIRECTORY_PATTERN 
-      = Pattern.compile("(lucene|solr)/build/(?:contrib/)?(.*)/classes/(?:java|test)");
-  private static final String UNWANTED_INTERNAL_DEPENDENCIES
-      = "/(?:test-)?lib/|test-framework/classes/java|/test-files|/resources";
-  private static final Pattern SHARED_EXTERNAL_DEPENDENCIES_PATTERN
-      = Pattern.compile("((?:solr|lucene)/(?!test-framework).*)/((?:test-)?)lib/");
-
-  private static final String DEPENDENCY_MANAGEMENT_PROPERTY = "lucene.solr.dependency.management";
-  private static final String IVY_USER_DIR_PROPERTY = "ivy.default.ivy.user.dir";
-  private static final Properties allProperties = new Properties();
-  private static final Set<String> modulesWithSeparateCompileAndTestPOMs = new HashSet<>();
-
-  private static final Set<String> globalOptionalExternalDependencies = new HashSet<>();
-  private static final Map<String,Set<String>> perModuleOptionalExternalDependencies = new HashMap<>();
-  private static final Set<String> modulesWithTransitiveDependencies = new HashSet<>();
-  static {
-    // Add modules here that have split compile and test POMs
-    // - they need compile-scope deps to also be test-scope deps.
-    modulesWithSeparateCompileAndTestPOMs.addAll
-        (Arrays.asList("lucene-core", "lucene-codecs", "solr-core", "solr-solrj"));
-
-    // Add external dependencies here that should be optional for all modules
-    // (i.e., not invoke Maven's transitive dependency mechanism).
-    // Format is "groupId:artifactId"
-    globalOptionalExternalDependencies.addAll(Arrays.asList
-        ("org.slf4j:jul-to-slf4j", "org.slf4j:slf4j-log4j12"));
-
-    // Add modules here that should NOT have their dependencies
-    // excluded in the grandparent POM's dependencyManagement section,
-    // thus enabling their dependencies to be transitive.
-    modulesWithTransitiveDependencies.addAll(Arrays.asList("lucene-test-framework"));
-  }
-
-  private final XPath xpath = XPathFactory.newInstance().newXPath();
-  private final SortedMap<String,SortedSet<String>> internalCompileScopeDependencies
-      = new TreeMap<>();
-  private final Set<String> nonJarDependencies = new HashSet<>();
-  private final Map<String,Set<String>> dependencyClassifiers = new HashMap<>();
-  private final Map<String,Set<String>> interModuleExternalCompileScopeDependencies = new HashMap<>();
-  private final Map<String,Set<String>> interModuleExternalTestScopeDependencies = new HashMap<>();
-  private final Map<String,SortedSet<ExternalDependency>> allExternalDependencies
-     = new HashMap<>();
-  private final DocumentBuilder documentBuilder;
-  private File ivyCacheDir;
-  private Pattern internalJarPattern;
-  private Map<String,String> ivyModuleInfo;
-
-
-  /**
-   * All ivy.xml files to get external dependencies from.
-   */
-  private Resources ivyXmlResources = new Resources();
-
-  /**
-   * Centralized Ivy versions properties file
-   */
-  private File centralizedVersionsFile;
-
-  /**
-   * Module dependencies properties file, generated by task -append-module-dependencies-properties.
-   */
-  private File moduleDependenciesPropertiesFile;
-
-  /**
-   * Where all properties are written, to be used to filter POM templates when copying them.
-   */
-  private File mavenDependenciesFiltersFile;
-
-  /**
-   * A logging level associated with verbose logging.
-   */
-  private int verboseLevel = Project.MSG_VERBOSE;
-
-  /**
-   * Adds a set of ivy.xml resources to check.
-   */
-  public void add(ResourceCollection rc) {
-    ivyXmlResources.add(rc);
-  }
-
-  public void setVerbose(boolean verbose) {
-    verboseLevel = (verbose ? Project.MSG_VERBOSE : Project.MSG_INFO);
-  }
-
-  public void setCentralizedVersionsFile(File file) {
-    centralizedVersionsFile = file;
-  }
-
-  public void setModuleDependenciesPropertiesFile(File file) {
-    moduleDependenciesPropertiesFile = file;
-  }
-  
-  public void setMavenDependenciesFiltersFile(File file) {
-    mavenDependenciesFiltersFile = file;
-  }
-
-  public GetMavenDependenciesTask() {
-    try {
-      documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-    } catch (ParserConfigurationException e) {
-      throw new BuildException(e);
-    }
-  }
-  
-  /**
-   * Collect dependency information from Ant build.xml and ivy.xml files
-   * and from ivy-versions.properties, then write out an Ant filters file
-   * to be used when copying POMs.
-   */
-  @Override
-  public void execute() throws BuildException {
-    // Local:   lucene/build/analysis/common/lucene-analyzers-common-5.0-SNAPSHOT.jar
-    // Jenkins: lucene/build/analysis/common/lucene-analyzers-common-5.0-2013-10-31_18-52-24.jar
-    // Also support any custom version, which won't necessarily conform to any predefined pattern.
-    internalJarPattern = Pattern.compile(".*(lucene|solr)([^/]*?)-"
-        + Pattern.quote(getProject().getProperty("version")) + "\\.jar");
-
-    ivyModuleInfo = getIvyModuleInfo(ivyXmlResources, documentBuilder, xpath);
-
-    setInternalDependencyProperties();            // side-effect: all modules' internal deps are recorded
-    setExternalDependencyProperties();            // side-effect: all modules' external deps are recorded
-    setGrandparentDependencyManagementProperty(); // uses deps recorded in above two methods
-    writeFiltersFile();
-  }
-
-  /**
-   * Write out an Ant filters file to be used when copying POMs.
-   */
-  private void writeFiltersFile() {
-    Writer writer = null;
-    try {
-      FileOutputStream outputStream = new FileOutputStream(mavenDependenciesFiltersFile);
-      writer = new OutputStreamWriter(outputStream, StandardCharsets.ISO_8859_1);
-      allProperties.store(writer, null);
-    } catch (FileNotFoundException e) {
-      throw new BuildException("Can't find file: '" + mavenDependenciesFiltersFile.getPath() + "'", e);
-    } catch (IOException e) {
-      throw new BuildException("Exception writing out '" + mavenDependenciesFiltersFile.getPath() + "'", e);
-    } finally {
-      if (null != writer) {
-        try {
-          writer.close();
-        } catch (IOException e) {
-          // ignore
-        }
-      }
-    }
-  }
-
-  /**
-   * Visits all ivy.xml files and collects module and organisation attributes into a map.
-   */
-  private static Map<String,String> getIvyModuleInfo(Resources ivyXmlResources,
-      DocumentBuilder documentBuilder, XPath xpath) {
-    Map<String,String> ivyInfoModuleToOrganisation = new HashMap<String,String>();
-    traverseIvyXmlResources(ivyXmlResources, new Consumer<File>() {
-      @Override
-      public void accept(File f) {
-        try {
-          Document document = documentBuilder.parse(f);
-          {
-            String infoPath = "/ivy-module/info";
-            NodeList infos = (NodeList)xpath.evaluate(infoPath, document, XPathConstants.NODESET);
-            for (int infoNum = 0 ; infoNum < infos.getLength() ; ++infoNum) {
-              Element infoElement = (Element)infos.item(infoNum);
-              String infoOrg = infoElement.getAttribute("organisation");
-              String infoOrgSuffix = infoOrg.substring(infoOrg.lastIndexOf('.')+1);
-              String infoModule = infoElement.getAttribute("module");
-              String module = infoOrgSuffix+"-"+infoModule;
-              ivyInfoModuleToOrganisation.put(module, infoOrg);
-            }
-          }
-        } catch (XPathExpressionException | IOException | SAXException e) {
-          throw new RuntimeException(e);
-        }
-      }
-    });
-    return ivyInfoModuleToOrganisation;
-  }
-
-  /**
-   * Collects external dependencies from each ivy.xml file and sets
-   * external dependency properties to be inserted into modules' POMs. 
-   */
-  private void setExternalDependencyProperties() {
-    traverseIvyXmlResources(ivyXmlResources, new Consumer<File>() {
-      @Override
-      public void accept(File f) {
-        try {
-        collectExternalDependenciesFromIvyXmlFile(f);
-        } catch (XPathExpressionException | IOException | SAXException e) {
-          throw new RuntimeException(e);
-        }
-      }
-    });
-    addSharedExternalDependencies();
-    setExternalDependencyXmlProperties();
-  }
-
-  private static void traverseIvyXmlResources(Resources ivyXmlResources, Consumer<File> ivyXmlFileConsumer) {
-    @SuppressWarnings("unchecked")
-    Iterator<Resource> iter = (Iterator<Resource>)ivyXmlResources.iterator();
-    while (iter.hasNext()) {
-      final Resource resource = iter.next();
-      if ( ! resource.isExists()) {
-        throw new BuildException("Resource does not exist: " + resource.getName());
-      }
-      if ( ! (resource instanceof FileResource)) {
-        throw new BuildException("Only filesystem resources are supported: "
-            + resource.getName() + ", was: " + resource.getClass().getName());
-      }
-
-      File ivyXmlFile = ((FileResource)resource).getFile();
-      try {
-        ivyXmlFileConsumer.accept(ivyXmlFile);
-      } catch (BuildException e) {
-        throw e;
-      } catch (Exception e) {
-        throw new BuildException("Exception reading file " + ivyXmlFile.getPath() + ": " + e, e);
-      }
-    }
-  }
-
-  /**
-   * For each module that includes other modules' external dependencies via
-   * including all files under their ".../lib/" dirs in their (test.)classpath,
-   * add the other modules' dependencies to its set of external dependencies. 
-   */
-  private void addSharedExternalDependencies() {
-    // Delay adding shared compile-scope dependencies until after all have been processed,
-    // so dependency sharing is limited to a depth of one.
-    Map<String,SortedSet<ExternalDependency>> sharedDependencies = new HashMap<>();
-    for (Map.Entry<String, Set<String>> entry : interModuleExternalCompileScopeDependencies.entrySet()) {
-      TreeSet<ExternalDependency> deps = new TreeSet<>();
-      sharedDependencies.put(entry.getKey(), deps);
-      Set<String> moduleDependencies = entry.getValue();
-      if (null != moduleDependencies) {
-        for (String otherArtifactId : moduleDependencies) {
-          SortedSet<ExternalDependency> otherExtDeps = allExternalDependencies.get(otherArtifactId); 
-          if (null != otherExtDeps) {
-            for (ExternalDependency otherDep : otherExtDeps) {
-              if ( ! otherDep.isTestDependency) {
-                deps.add(otherDep);
-              }
-            }
-          }
-        }
-      }
-    }
-    for (Map.Entry<String, Set<String>> entry : interModuleExternalTestScopeDependencies.entrySet()) {
-      String module = entry.getKey();
-      SortedSet<ExternalDependency> deps = sharedDependencies.get(module);
-      if (null == deps) {
-        deps = new TreeSet<>();
-        sharedDependencies.put(module, deps);
-      }
-      Set<String> moduleDependencies = entry.getValue();
-      if (null != moduleDependencies) {
-        for (String otherArtifactId : moduleDependencies) {
-          int testScopePos = otherArtifactId.indexOf(":test");
-          boolean isTestScope = false;
-          if (-1 != testScopePos) {
-            otherArtifactId = otherArtifactId.substring(0, testScopePos);
-            isTestScope = true;
-          }
-          SortedSet<ExternalDependency> otherExtDeps = allExternalDependencies.get(otherArtifactId);
-          if (null != otherExtDeps) {
-            for (ExternalDependency otherDep : otherExtDeps) {
-              if (otherDep.isTestDependency == isTestScope) {
-                if (  ! deps.contains(otherDep)
-                   && (  null == allExternalDependencies.get(module)
-                      || ! allExternalDependencies.get(module).contains(otherDep))) {
-                  // Add test-scope clone only if it's not already a compile-scope dependency. 
-                  ExternalDependency otherDepTestScope = new ExternalDependency
-                      (otherDep.groupId, otherDep.artifactId, otherDep.classifier, true, otherDep.isOptional);
-                  deps.add(otherDepTestScope);
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    for (Map.Entry<String, SortedSet<ExternalDependency>> entry : sharedDependencies.entrySet()) {
-      String module = entry.getKey();
-      SortedSet<ExternalDependency> deps = allExternalDependencies.get(module);
-      if (null == deps) {
-        deps = new TreeSet<>();
-        allExternalDependencies.put(module, deps);
-      }
-      for (ExternalDependency dep : entry.getValue()) {
-        String dependencyCoordinate = dep.groupId + ":" + dep.artifactId;
-        if (globalOptionalExternalDependencies.contains(dependencyCoordinate)
-            || (perModuleOptionalExternalDependencies.containsKey(module)
-                && perModuleOptionalExternalDependencies.get(module).contains(dependencyCoordinate))) {
-          // make a copy of the dep and set optional=true
-          dep = new ExternalDependency(dep.groupId, dep.artifactId, dep.classifier, dep.isTestDependency, true);
-        }
-        deps.add(dep);
-      }
-    }
-  }
-
-  /**
-   * For each module, sets a compile-scope and a test-scope property
-   * with values that contain the appropriate &lt;dependency&gt;
-   * snippets.
-   */
-  private void setExternalDependencyXmlProperties() {
-    for (String module : internalCompileScopeDependencies.keySet()) { // get full module list
-      StringBuilder compileScopeBuilder = new StringBuilder();
-      StringBuilder testScopeBuilder = new StringBuilder();
-      SortedSet<ExternalDependency> extDeps = allExternalDependencies.get(module);
-      if (null != extDeps) {
-        for (ExternalDependency dep : extDeps) {
-          StringBuilder builder = dep.isTestDependency ? testScopeBuilder : compileScopeBuilder;
-          appendDependencyXml(builder, dep.groupId, dep.artifactId, "    ", null, 
-                              dep.isTestDependency, dep.isOptional, dep.classifier, null);
-          // Test POMs for solrj, solr-core, lucene-codecs and lucene-core modules
-          // need to include all compile-scope dependencies as test-scope dependencies
-          // since we've turned off transitive dependency resolution.
-          if ( ! dep.isTestDependency && modulesWithSeparateCompileAndTestPOMs.contains(module)) {
-            appendDependencyXml(testScopeBuilder, dep.groupId, dep.artifactId, "    ", null,
-                                true, dep.isOptional, dep.classifier, null);
-          }
-        }
-      }
-      if (compileScopeBuilder.length() > 0) {
-        compileScopeBuilder.setLength(compileScopeBuilder.length() - 1); // drop trailing newline
-      }
-      if (testScopeBuilder.length() > 0) {
-        testScopeBuilder.setLength(testScopeBuilder.length() - 1); // drop trailing newline
-      }
-      allProperties.setProperty(module + ".external.dependencies", compileScopeBuilder.toString());
-      allProperties.setProperty(module + ".external.test.dependencies", testScopeBuilder.toString());
-    }
-  }
-
-  /**
-   * Sets the property to be inserted into the grandparent POM's 
-   * &lt;dependencyManagement&gt; section.
-   */
-  private void setGrandparentDependencyManagementProperty() {
-    StringBuilder builder = new StringBuilder();
-    appendAllInternalDependencies(builder);
-    Map<String,String> versionsMap = new HashMap<>();
-    appendAllExternalDependencies(builder, versionsMap);
-    builder.setLength(builder.length() - 1); // drop trailing newline
-    allProperties.setProperty(DEPENDENCY_MANAGEMENT_PROPERTY, builder.toString());
-    for (Map.Entry<String,String> entry : versionsMap.entrySet()) {
-      allProperties.setProperty(entry.getKey(), entry.getValue());
-    }
-  }
-
-  /**
-   * For each artifact in the project, append a dependency with version
-   * ${project.version} to the grandparent POM's &lt;dependencyManagement&gt;
-   * section.  An &lt;exclusion&gt; is added for each of the artifact's
-   * dependencies.
-   */
-  private void appendAllInternalDependencies(StringBuilder builder) {
-    for (Map.Entry<String, SortedSet<String>> entry : internalCompileScopeDependencies.entrySet()) {
-      String artifactId = entry.getKey();
-      List<String> exclusions = new ArrayList<>(entry.getValue());
-      SortedSet<ExternalDependency> extDeps = allExternalDependencies.get(artifactId);
-      if (null != extDeps) {
-        for (ExternalDependency externalDependency : extDeps) {
-          if ( ! externalDependency.isTestDependency && ! externalDependency.isOptional) {
-            exclusions.add(externalDependency.groupId + ':' + externalDependency.artifactId);
-          }
-        }
-      }
-      String groupId = ivyModuleInfo.get(artifactId);
-      appendDependencyXml(builder, groupId, artifactId, "      ", "${project.version}", false, false, null, exclusions);
-    }
-  }
-
-  /**
-   * Sets the ivyCacheDir field, to either the ${ivy.default.ivy.user.dir} 
-   * property, or if that's not set, to the default ~/.ivy2/.
-   */
-  private File getIvyCacheDir() {
-    String ivyUserDirName = getProject().getUserProperty(IVY_USER_DIR_PROPERTY);
-    if (null == ivyUserDirName) {
-      ivyUserDirName = getProject().getProperty(IVY_USER_DIR_PROPERTY);
-      if (null == ivyUserDirName) {
-        ivyUserDirName = System.getProperty("user.home") + System.getProperty("file.separator") + ".ivy2";
-      }
-    }
-    File ivyUserDir = new File(ivyUserDirName);
-    if ( ! ivyUserDir.exists()) {
-      throw new BuildException("Ivy user dir does not exist: '" + ivyUserDir.getPath() + "'");
-    }
-    File dir = new File(ivyUserDir, "cache");
-    if ( ! dir.exists()) {
-      throw new BuildException("Ivy cache dir does not exist: '" + ivyCacheDir.getPath() + "'");
-    }
-    return dir;
-  }
-
-  /**
-   * Append each dependency listed in the centralized Ivy versions file
-   * to the grandparent POM's &lt;dependencyManagement&gt; section.  
-   * An &lt;exclusion&gt; is added for each of the artifact's dependencies,
-   * which are collected from the artifact's ivy.xml from the Ivy cache.
-   * 
-   * Also add a version property for each dependency.
-   */
-  private void appendAllExternalDependencies(StringBuilder dependenciesBuilder, Map<String,String> versionsMap) {
-    log("Loading centralized ivy versions from: " + centralizedVersionsFile, verboseLevel);
-    ivyCacheDir = getIvyCacheDir();
-    Properties versions = new InterpolatedProperties();
-    try (InputStream inputStream = new FileInputStream(centralizedVersionsFile);
-         Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
-      versions.load(reader);
-    } catch (IOException e) {
-      throw new BuildException("Exception reading centralized versions file " + centralizedVersionsFile.getPath(), e);
-    } 
-    SortedSet<Map.Entry<?,?>> sortedEntries = new TreeSet<>(new Comparator<Map.Entry<?,?>>() {
-      @Override public int compare(Map.Entry<?,?> o1, Map.Entry<?,?> o2) {
-        return ((String)o1.getKey()).compareTo((String)o2.getKey());
-      }
-    });
-    sortedEntries.addAll(versions.entrySet());
-    for (Map.Entry<?,?> entry : sortedEntries) {
-      String key = (String)entry.getKey();
-      Matcher matcher = COORDINATE_KEY_PATTERN.matcher(key);
-      if (matcher.lookingAt()) {
-        String groupId = matcher.group(1);
-        String artifactId = matcher.group(2);
-        String coordinate = groupId + ':' + artifactId;
-        String version = (String)entry.getValue();
-        versionsMap.put(coordinate + ".version", version);
-        if ( ! nonJarDependencies.contains(coordinate)) {
-          Set<String> classifiers = dependencyClassifiers.get(coordinate);
-          if (null != classifiers) {
-            for (String classifier : classifiers) {
-              Collection<String> exclusions = getTransitiveDependenciesFromIvyCache(groupId, artifactId, version);
-              appendDependencyXml
-                  (dependenciesBuilder, groupId, artifactId, "      ", version, false, false, classifier, exclusions);
-            }
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * Collect transitive compile-scope dependencies for the given artifact's
-   * ivy.xml from the Ivy cache, using the default ivy pattern 
-   * "[organisation]/[module]/ivy-[revision].xml".  See 
-   * <a href="http://ant.apache.org/ivy/history/latest-milestone/settings/caches.html"
-   * >the Ivy cache documentation</a>.
-   */
-  private Collection<String> getTransitiveDependenciesFromIvyCache
-  (String groupId, String artifactId, String version) {
-    SortedSet<String> transitiveDependencies = new TreeSet<>();
-    //                                      E.g. ~/.ivy2/cache/xerces/xercesImpl/ivy-2.9.1.xml
-    File ivyXmlFile = new File(new File(new File(ivyCacheDir, groupId), artifactId), "ivy-" + version + ".xml");
-    if ( ! ivyXmlFile.exists()) {
-      throw new BuildException("File not found: " + ivyXmlFile.getPath());
-    }
-    try {
-      Document document = documentBuilder.parse(ivyXmlFile);
-      String dependencyPath = "/ivy-module/dependencies/dependency"
-                            + "[   not(starts-with(@conf,'test->'))"
-                            + "and not(starts-with(@conf,'provided->'))"
-                            + "and not(starts-with(@conf,'optional->'))]";
-      NodeList dependencies = (NodeList)xpath.evaluate(dependencyPath, document, XPathConstants.NODESET);
-      for (int i = 0 ; i < dependencies.getLength() ; ++i) {
-        Element dependency = (Element)dependencies.item(i);
-        transitiveDependencies.add(dependency.getAttribute("org") + ':' + dependency.getAttribute("name"));
-      }
-    } catch (Exception e) {
-      throw new BuildException( "Exception collecting transitive dependencies for " 
-                              + groupId + ':' + artifactId + ':' + version + " from "
-                              + ivyXmlFile.getAbsolutePath(), e);
-    }
-    return transitiveDependencies;
-  }
-
-  /**
-   * Sets the internal dependencies compile and test properties to be inserted 
-   * into modules' POMs.
-   * 
-   * Also collects shared external dependencies, 
-   * e.g. solr-core wants all of solrj's external dependencies 
-   */
-  private void  setInternalDependencyProperties() {
-    log("Loading module dependencies from: " + moduleDependenciesPropertiesFile, verboseLevel);
-    Properties moduleDependencies = new Properties();
-    try (InputStream inputStream = new FileInputStream(moduleDependenciesPropertiesFile);
-         Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
-      moduleDependencies.load(reader);
-    } catch (FileNotFoundException e) {
-      throw new BuildException("Properties file does not exist: " + moduleDependenciesPropertiesFile.getPath());
-    } catch (IOException e) {
-      throw new BuildException("Exception reading properties file " + moduleDependenciesPropertiesFile.getPath(), e);
-    }
-    Map<String,SortedSet<String>> testScopeDependencies = new HashMap<>();
-    Map<String, String> testScopePropertyKeys = new HashMap<>();
-    for (Map.Entry<?,?> entry : moduleDependencies.entrySet()) {
-      String newPropertyKey = (String)entry.getKey();
-      StringBuilder newPropertyValue = new StringBuilder();
-      String value = (String)entry.getValue();
-      Matcher matcher = MODULE_DEPENDENCIES_COORDINATE_KEY_PATTERN.matcher(newPropertyKey);
-      if ( ! matcher.matches()) {
-        throw new BuildException("Malformed module dependencies property key: '" + newPropertyKey + "'");
-      }
-      String antProjectName = matcher.group(1);
-      boolean isTest = null != matcher.group(2);
-      String artifactName = antProjectToArtifactName(antProjectName);
-      newPropertyKey = artifactName + (isTest ? ".internal.test" : ".internal") + ".dependencies"; // Add ".internal"
-      if (isTest) {
-        testScopePropertyKeys.put(artifactName, newPropertyKey);
-      }
-      if (null == value || value.isEmpty()) {
-        allProperties.setProperty(newPropertyKey, "");
-        Map<String,SortedSet<String>> scopedDependencies
-            = isTest ? testScopeDependencies : internalCompileScopeDependencies;
-        scopedDependencies.put(artifactName, new TreeSet<String>());
-      } else {
-        // Lucene analysis modules' build dirs do not include hyphens, but Solr contribs' build dirs do
-        String origModuleDir = antProjectName.replace("analyzers-", "analysis/");
-        // Exclude the module's own build output, in addition to UNWANTED_INTERNAL_DEPENDENCIES
-        Pattern unwantedInternalDependencies = Pattern.compile
-            ("(?:lucene/build/|solr/build/(?:contrib/)?)" + origModuleDir + "/" // require dir separator 
-             + "|" + UNWANTED_INTERNAL_DEPENDENCIES);
-        SortedSet<String> sortedDeps = new TreeSet<>();
-        for (String dependency : value.split(",")) {
-          matcher = SHARED_EXTERNAL_DEPENDENCIES_PATTERN.matcher(dependency);
-          if (matcher.find()) {
-            String otherArtifactName = matcher.group(1);
-            boolean isTestScope = null != matcher.group(2) && matcher.group(2).length() > 0;
-            otherArtifactName = otherArtifactName.replace('/', '-');
-            otherArtifactName = otherArtifactName.replace("lucene-analysis", "lucene-analyzers");
-            otherArtifactName = otherArtifactName.replace("solr-contrib-solr-", "solr-");
-            otherArtifactName = otherArtifactName.replace("solr-contrib-", "solr-");
-            if ( ! otherArtifactName.equals(artifactName)) {
-              Map<String,Set<String>> sharedDeps
-                  = isTest ? interModuleExternalTestScopeDependencies : interModuleExternalCompileScopeDependencies;
-              Set<String> sharedSet = sharedDeps.get(artifactName);
-              if (null == sharedSet) {
-                sharedSet = new HashSet<>();
-                sharedDeps.put(artifactName, sharedSet);
-              }
-              if (isTestScope) {
-                otherArtifactName += ":test";
-              }
-              sharedSet.add(otherArtifactName);
-            }
-          }
-          matcher = unwantedInternalDependencies.matcher(dependency);
-          if (matcher.find()) {
-            continue;  // skip external (/(test-)lib/), and non-jar and unwanted (self) internal deps
-          }
-          String artifactId = dependencyToArtifactId(newPropertyKey, dependency);
-          String groupId = ivyModuleInfo.get(artifactId);
-          String coordinate = groupId + ':' + artifactId;
-          sortedDeps.add(coordinate);
-        }
-        if (isTest) {  // Don't set test-scope properties until all compile-scope deps have been seen
-          testScopeDependencies.put(artifactName, sortedDeps);
-        } else {
-          internalCompileScopeDependencies.put(artifactName, sortedDeps);
-          for (String dependency : sortedDeps) {
-            int splitPos = dependency.indexOf(':');
-            String groupId = dependency.substring(0, splitPos);
-            String artifactId = dependency.substring(splitPos + 1);
-            appendDependencyXml(newPropertyValue, groupId, artifactId, "    ", null, false, false, null, null);
-          }
-          if (newPropertyValue.length() > 0) {
-            newPropertyValue.setLength(newPropertyValue.length() - 1); // drop trailing newline
-          }
-          allProperties.setProperty(newPropertyKey, newPropertyValue.toString());
-        }
-      }
-    }
-    // Now that all compile-scope dependencies have been seen, include only those test-scope
-    // dependencies that are not also compile-scope dependencies.
-    for (Map.Entry<String,SortedSet<String>> entry : testScopeDependencies.entrySet()) {
-      String module = entry.getKey();
-      SortedSet<String> testDeps = entry.getValue();
-      SortedSet<String> compileDeps = internalCompileScopeDependencies.get(module);
-      if (null == compileDeps) {
-        throw new BuildException("Can't find compile scope dependencies for module " + module);
-      }
-      StringBuilder newPropertyValue = new StringBuilder();
-      for (String dependency : testDeps) {
-        // modules with separate compile-scope and test-scope POMs need their compile-scope deps
-        // included in their test-scope deps.
-        if (modulesWithSeparateCompileAndTestPOMs.contains(module) || ! compileDeps.contains(dependency)) {
-          int splitPos = dependency.indexOf(':');
-          String groupId = dependency.substring(0, splitPos);
-          String artifactId = dependency.substring(splitPos + 1);
-          appendDependencyXml(newPropertyValue, groupId, artifactId, "    ", null, true, false, null, null);
-        }
-      }
-      if (newPropertyValue.length() > 0) {
-        newPropertyValue.setLength(newPropertyValue.length() - 1); // drop trailing newline
-      }
-      allProperties.setProperty(testScopePropertyKeys.get(module), newPropertyValue.toString());
-    }
-  }
-
-  /**
-   * Converts either a compile output directory or an internal jar
-   * dependency, taken from an Ant (test.)classpath, into an artifactId
-   */
-  private String dependencyToArtifactId(String newPropertyKey, String dependency) {
-    StringBuilder artifactId = new StringBuilder();
-    Matcher matcher = COMPILATION_OUTPUT_DIRECTORY_PATTERN.matcher(dependency);
-    if (matcher.matches()) {
-      // Pattern.compile("(lucene|solr)/build/(.*)/classes/java");
-      String artifact = matcher.group(2);
-      artifact = artifact.replace('/', '-');
-      artifact = artifact.replaceAll("(?<!solr-)analysis-", "analyzers-");
-      if ("lucene".equals(matcher.group(1))) {
-        artifactId.append("lucene-");
-      }
-      artifactId.append(artifact);
-    } else {
-      matcher = internalJarPattern.matcher(dependency);
-      if (matcher.matches()) {
-        // internalJarPattern is /.*(lucene|solr)([^/]*?)-<version>\.jar/,
-        // where <version> is the value of the Ant "version" property
-        artifactId.append(matcher.group(1));
-        artifactId.append(matcher.group(2));
-      } else {
-        throw new BuildException
-            ("Malformed module dependency from '" + newPropertyKey + "': '" + dependency + "'");
-      }
-    }
-    return artifactId.toString();
-  }
-
-  /**
-   * Convert Ant project names to artifact names: prepend "lucene-"
-   * to Lucene project names
-   */
-  private String antProjectToArtifactName(String origModule) {
-    String module = origModule;
-    if ( ! origModule.startsWith("solr-")) { // lucene modules names don't have "lucene-" prepended
-      module = "lucene-" + module;
-    }
-    return module;
-  }
-
-  /**
-   * Collect external dependencies from the given ivy.xml file, constructing
-   * property values containing &lt;dependency&gt; snippets, which will be
-   * filtered (substituted) when copying the POM for the module corresponding
-   * to the given ivy.xml file.
-   */
-  private void collectExternalDependenciesFromIvyXmlFile(File ivyXmlFile)
-      throws XPathExpressionException, IOException, SAXException {
-    String module = getModuleName(ivyXmlFile);
-    log("Collecting external dependencies from: " + ivyXmlFile.getPath(), verboseLevel);
-    Document document = documentBuilder.parse(ivyXmlFile);
-    // Exclude the 'start' configuration in solr/server/ivy.xml
-    String dependencyPath = "/ivy-module/dependencies/dependency[not(starts-with(@conf,'start'))]";
-    NodeList dependencies = (NodeList)xpath.evaluate(dependencyPath, document, XPathConstants.NODESET);
-    for (int depNum = 0 ; depNum < dependencies.getLength() ; ++depNum) {
-      Element dependency = (Element)dependencies.item(depNum);
-      String groupId = dependency.getAttribute("org");
-      String artifactId = dependency.getAttribute("name");
-      String dependencyCoordinate = groupId + ':' + artifactId;
-      Set<String> classifiers = dependencyClassifiers.get(dependencyCoordinate);
-      if (null == classifiers) {
-        classifiers = new HashSet<>();
-        dependencyClassifiers.put(dependencyCoordinate, classifiers);
-      }
-      String conf = dependency.getAttribute("conf");
-      boolean confContainsTest = conf.contains("test");
-      boolean isOptional = globalOptionalExternalDependencies.contains(dependencyCoordinate)
-          || ( perModuleOptionalExternalDependencies.containsKey(module)
-              && perModuleOptionalExternalDependencies.get(module).contains(dependencyCoordinate));
-      SortedSet<ExternalDependency> deps = allExternalDependencies.get(module);
-      if (null == deps) {
-        deps = new TreeSet<>();
-        allExternalDependencies.put(module, deps);
-      }
-      NodeList artifacts = null;
-      if (dependency.hasChildNodes()) {
-        artifacts = (NodeList)xpath.evaluate("artifact", dependency, XPathConstants.NODESET);
-      }
-      if (null != artifacts && artifacts.getLength() > 0) {
-        for (int artifactNum = 0 ; artifactNum < artifacts.getLength() ; ++artifactNum) {
-          Element artifact = (Element)artifacts.item(artifactNum);
-          String type = artifact.getAttribute("type");
-          String ext = artifact.getAttribute("ext");
-          // When conf contains BOTH "test" and "compile", and type != "test", this is NOT a test dependency
-          boolean isTestDependency = confContainsTest && (type.equals("test") || ! conf.contains("compile"));
-          if ((type.isEmpty() && ext.isEmpty()) || type.equals("jar") || ext.equals("jar")) {
-            String classifier = artifact.getAttribute("maven:classifier");
-            if (classifier.isEmpty()) {
-              classifier = null;
-            }
-            classifiers.add(classifier);
-            deps.add(new ExternalDependency(groupId, artifactId, classifier, isTestDependency, isOptional));
-          } else { // not a jar
-            nonJarDependencies.add(dependencyCoordinate);
-          }
-        }
-      } else {
-        classifiers.add(null);
-        deps.add(new ExternalDependency(groupId, artifactId, null, confContainsTest, isOptional));
-      }
-    }
-  }
-
-  /**
-   * Stores information about an external dependency
-   */
-  private static class ExternalDependency implements Comparable<ExternalDependency> {
-    String groupId;
-    String artifactId;
-    boolean isTestDependency;
-    boolean isOptional;
-    String classifier;
-    
-    public ExternalDependency
-        (String groupId, String artifactId, String classifier, boolean isTestDependency, boolean isOptional) {
-      this.groupId = groupId;
-      this.artifactId = artifactId;
-      this.classifier = classifier;
-      this.isTestDependency = isTestDependency;
-      this.isOptional = isOptional;
-    }
-    
-    @Override
-    public boolean equals(Object o) {
-      if ( ! (o instanceof ExternalDependency)) {
-        return false;
-      }
-      ExternalDependency other = (ExternalDependency)o;
-      return groupId.equals(other.groupId) 
-          && artifactId.equals(other.artifactId) 
-          && isTestDependency == other.isTestDependency
-          && isOptional == other.isOptional
-          && classifier.equals(other.classifier);
-    } 
-    
-    @Override
-    public int hashCode() {
-      return groupId.hashCode() * 31
-          + artifactId.hashCode() * 31
-          + (isTestDependency ? 31 : 0)
-          + (isOptional ? 31 : 0)
-          + classifier.hashCode();
-    }
-
-    @Override
-    public int compareTo(ExternalDependency other) {
-      int comparison = groupId.compareTo(other.groupId);
-      if (0 != comparison) {
-        return comparison;
-      }
-      comparison = artifactId.compareTo(other.artifactId);
-      if (0 != comparison) {
-        return comparison;
-      }
-      if (null == classifier) {
-        if (null != other.classifier) {
-          return -1;
-        }
-      } else if (null == other.classifier) { // classifier is not null
-        return 1;
-      } else {                               // neither classifier is  null
-        if (0 != (comparison = classifier.compareTo(other.classifier))) {
-          return comparison;
-        }
-      }
-      // test and optional don't matter in this sort
-      return 0;
-    }
-  }
-  
-  /**
-   * Extract module name from ivy.xml path.
-   */
-  private String getModuleName(File ivyXmlFile) {
-    String path = ivyXmlFile.getAbsolutePath();
-    Matcher matcher = PROPERTY_PREFIX_FROM_IVY_XML_FILE_PATTERN.matcher(path);
-    if ( ! matcher.find()) {
-      throw new BuildException("Can't get module name from ivy.xml path: " + path);
-    }
-    StringBuilder builder = new StringBuilder();
-    builder.append(matcher.group(1));
-    if (null != matcher.group(2)) { // "lucene/analysis/..."
-      builder.append("-analyzers");
-    } else if (null != matcher.group(3)) { // "solr/example/..."
-      builder.append("-example");
-    } else if (null != matcher.group(4)) { // "solr/server/..."
-      builder.append("-server");
-    }
-    builder.append('-');
-    builder.append(matcher.group(5));
-    return builder.toString().replace("solr-solr-", "solr-");
-  }
-
-/**
- * Appends a &lt;dependency&gt; snippet to the given builder.
- */
-  private void appendDependencyXml(StringBuilder builder, String groupId, String artifactId, 
-                                   String indent, String version, boolean isTestDependency, 
-                                   boolean isOptional, String classifier, Collection<String> exclusions) {
-    builder.append(indent).append("<dependency>\n");
-    builder.append(indent).append("  <groupId>").append(groupId).append("</groupId>\n");
-    builder.append(indent).append("  <artifactId>").append(artifactId).append("</artifactId>\n");
-    if (null != version) {
-      builder.append(indent).append("  <version>").append(version).append("</version>\n");
-    }
-    if (isTestDependency) {
-      builder.append(indent).append("  <scope>test</scope>\n");
-    }
-    if (isOptional) {
-      builder.append(indent).append("  <optional>true</optional>\n");
-    }
-    if (null != classifier) {
-      builder.append(indent).append("  <classifier>").append(classifier).append("</classifier>\n");
-    }
-    if ( ! modulesWithTransitiveDependencies.contains(artifactId) && null != exclusions && ! exclusions.isEmpty()) {
-      builder.append(indent).append("  <exclusions>\n");
-      for (String dependency : exclusions) {
-        int splitPos = dependency.indexOf(':');
-        String excludedGroupId = dependency.substring(0, splitPos);
-        String excludedArtifactId = dependency.substring(splitPos + 1);
-        builder.append(indent).append("    <exclusion>\n");
-        builder.append(indent).append("      <groupId>").append(excludedGroupId).append("</groupId>\n");
-        builder.append(indent).append("      <artifactId>").append(excludedArtifactId).append("</artifactId>\n");
-        builder.append(indent).append("    </exclusion>\n");
-      }
-      builder.append(indent).append("  </exclusions>\n");
-    }
-    builder.append(indent).append("</dependency>\n");
-  }
-}
diff --git a/lucene/tools/src/java/org/apache/lucene/dependencies/InterpolatedProperties.java b/lucene/tools/src/java/org/apache/lucene/dependencies/InterpolatedProperties.java
deleted file mode 100644
index 073db7b..0000000
--- a/lucene/tools/src/java/org/apache/lucene/dependencies/InterpolatedProperties.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.dependencies;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-/**
- * Parse a properties file, performing recursive Ant-like
- * property value interpolation, and return the resulting Properties.
- */
-public class InterpolatedProperties extends Properties {
-  private static final Pattern PROPERTY_REFERENCE_PATTERN = Pattern.compile("\\$\\{(?<name>[^}]+)\\}");
-
-  /**
-   * Loads the properties file via {@link Properties#load(InputStream)},
-   * then performs recursive Ant-like property value interpolation.
-   */
-  @Override
-  public void load(InputStream inStream) throws IOException {
-    throw new UnsupportedOperationException("InterpolatedProperties.load(InputStream) is not supported.");
-  }
-
-  /**
-   * Loads the properties file via {@link Properties#load(Reader)},
-   * then performs recursive Ant-like property value interpolation.
-   */
-  @Override
-  public void load(Reader reader) throws IOException {
-    Properties p = new Properties();
-    p.load(reader);
-
-    LinkedHashMap<String, String> props = new LinkedHashMap<>();
-    Enumeration<?> e = p.propertyNames();
-    while (e.hasMoreElements()) {
-      String key = (String) e.nextElement();
-      props.put(key, p.getProperty(key));
-    }
-
-    resolve(props).forEach((k, v) -> this.setProperty(k, v));
-  }
-
-  private static Map<String,String> resolve(Map<String,String> props) {
-    LinkedHashMap<String, String> resolved = new LinkedHashMap<>();
-    HashSet<String> recursive = new HashSet<>();
-    props.forEach((k, v) -> {
-      resolve(props, resolved, recursive, k, v);
-    });
-    return resolved;
-  }
-
-  private static String resolve(Map<String,String> props,
-                               LinkedHashMap<String, String> resolved,
-                               Set<String> recursive,
-                               String key,
-                               String value) {
-    if (value == null) {
-      throw new IllegalArgumentException("Missing replaced property key: " + key);
-    }
-
-    if (recursive.contains(key)) {
-      throw new IllegalArgumentException("Circular recursive property resolution: " + recursive);
-    }
-
-    if (!resolved.containsKey(key)) {
-      recursive.add(key);
-      StringBuffer buffer = new StringBuffer();
-      Matcher matcher = PROPERTY_REFERENCE_PATTERN.matcher(value);
-      while (matcher.find()) {
-        String referenced = matcher.group("name");
-        String concrete = resolve(props, resolved, recursive, referenced, props.get(referenced));
-        matcher.appendReplacement(buffer, Matcher.quoteReplacement(concrete));
-      }
-      matcher.appendTail(buffer);
-      resolved.put(key, buffer.toString());
-      recursive.remove(key);
-    }
-    assert resolved.get(key).equals(value);
-    return resolved.get(key);
-  }
-
-  public static void main(String [] args) {
-    {
-      Map<String, String> props = new LinkedHashMap<>();
-      props.put("a", "${b}");
-      props.put("b", "${c}");
-      props.put("c", "foo");
-      props.put("d", "${a}/${b}/${c}");
-      assertEquals(resolve(props), "a=foo", "b=foo", "c=foo", "d=foo/foo/foo");
-    }
-
-    {
-      Map<String, String> props = new LinkedHashMap<>();
-      props.put("a", "foo");
-      props.put("b", "${a}");
-      assertEquals(resolve(props), "a=foo", "b=foo");
-    }
-
-    {
-      Map<String, String> props = new LinkedHashMap<>();
-      props.put("a", "${b}");
-      props.put("b", "${c}");
-      props.put("c", "${a}");
-      try {
-        resolve(props);
-      } catch (IllegalArgumentException e) {
-        // Expected, circular reference.
-        if (!e.getMessage().contains("Circular recursive")) {
-          throw new AssertionError();
-        }
-      }
-    }
-
-    {
-      Map<String, String> props = new LinkedHashMap<>();
-      props.put("a", "${b}");
-      try {
-        resolve(props);
-      } catch (IllegalArgumentException e) {
-        // Expected, no referenced value.
-        if (!e.getMessage().contains("Missing replaced")) {
-          throw new AssertionError();
-        }
-      }
-    }
-  }
-
-  private static void assertEquals(Map<String,String> resolved, String... keyValuePairs) {
-    List<String> result = resolved.entrySet().stream().sorted((a, b) -> a.getKey().compareTo(b.getKey()))
-        .map(e -> e.getKey() + "=" + e.getValue())
-        .collect(Collectors.toList());
-    if (!result.equals(Arrays.asList(keyValuePairs))) {
-      throw new AssertionError("Mismatch: \n" + result + "\nExpected: " + Arrays.asList(keyValuePairs));
-    }
-  }
-}
diff --git a/lucene/tools/src/java/org/apache/lucene/validation/LibVersionsCheckTask.java b/lucene/tools/src/java/org/apache/lucene/validation/LibVersionsCheckTask.java
deleted file mode 100644
index 2b89703..0000000
--- a/lucene/tools/src/java/org/apache/lucene/validation/LibVersionsCheckTask.java
+++ /dev/null
@@ -1,903 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.validation;
-
-import org.apache.ivy.Ivy;
-import org.apache.ivy.core.LogOptions;
-import org.apache.ivy.core.report.ResolveReport;
-import org.apache.ivy.core.resolve.ResolveOptions;
-import org.apache.ivy.core.settings.IvySettings;
-import org.apache.ivy.plugins.conflict.NoConflictManager;
-import org.apache.lucene.dependencies.InterpolatedProperties;
-import org.apache.lucene.validation.ivyde.IvyNodeElement;
-import org.apache.lucene.validation.ivyde.IvyNodeElementAdapter;
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.ResourceCollection;
-import org.apache.tools.ant.types.resources.FileResource;
-import org.apache.tools.ant.types.resources.Resources;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXNotRecognizedException;
-import org.xml.sax.SAXNotSupportedException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import javax.xml.XMLConstants;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.nio.charset.StandardCharsets;
-import java.text.ParseException;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * An Ant task to verify that the '/org/name' keys in ivy-versions.properties
- * are sorted lexically and are neither duplicates nor orphans, and that all
- * dependencies in all ivy.xml files use rev="${/org/name}" format.
- */
-public class LibVersionsCheckTask extends Task {
-
-  private static final String IVY_XML_FILENAME = "ivy.xml";
-  private static final Pattern COORDINATE_KEY_PATTERN = Pattern.compile("(/([^/ \t\f]+)/([^=:/ \t\f]+))");
-  private static final Pattern BLANK_OR_COMMENT_LINE_PATTERN = Pattern.compile("[ \t\f]*(?:[#!].*)?");
-  private static final Pattern TRAILING_BACKSLASH_PATTERN = Pattern.compile("[^\\\\]*(\\\\+)$");
-  private static final Pattern LEADING_WHITESPACE_PATTERN = Pattern.compile("[ \t\f]+(.*)");
-  private static final Pattern WHITESPACE_GOODSTUFF_WHITESPACE_BACKSLASH_PATTERN
-      = Pattern.compile("[ \t\f]*(.*?)(?:(?<!\\\\)[ \t\f]*)?\\\\");
-  private static final Pattern TRAILING_WHITESPACE_BACKSLASH_PATTERN
-      = Pattern.compile("(.*?)(?:(?<!\\\\)[ \t\f]*)?\\\\");
-  private static final Pattern MODULE_NAME_PATTERN = Pattern.compile("\\smodule\\s*=\\s*[\"']([^\"']+)[\"']");
-  private static final Pattern MODULE_DIRECTORY_PATTERN 
-      = Pattern.compile(".*[/\\\\]((?:lucene|solr)[/\\\\].*)[/\\\\].*");
-  private static final SAXParserFactory SAX_PARSER_FACTORY = SAXParserFactory.newDefaultInstance();
-  static {
-    try {
-      SAX_PARSER_FACTORY.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
-    } catch (SAXNotRecognizedException | SAXNotSupportedException | ParserConfigurationException e) {
-      throw new Error(e);
-    }
-  }
-  private Ivy ivy;
-
-  /**
-   * All ivy.xml files to check.
-   */
-  private Resources ivyXmlResources = new Resources();
-
-  /**
-   * Centralized Ivy versions properties file: ivy-versions.properties
-   */
-  private File centralizedVersionsFile;
-
-  /**
-   * Centralized Ivy ignore conflicts file: ivy-ignore-conflicts.properties
-   */
-  private File ignoreConflictsFile;
-
-  /**
-   * Ivy settings file: top-level-ivy-settings.xml
-   */
-  private File topLevelIvySettingsFile;
-
-  /**
-   * Location of common build dir: lucene/build/
-   */
-  private File commonBuildDir;
-
-  /**
-   * Location of ivy cache resolution directory.
-   */
-  private File ivyResolutionCacheDir;
-  
-  /**
-   * Artifact lock strategy that Ivy should use.
-   */
-  private String ivyLockStrategy;
-  
-  /**
-   * A logging level associated with verbose logging.
-   */
-  private int verboseLevel = Project.MSG_VERBOSE;
-  
-  /**
-   * All /org/name keys found in ivy-versions.properties,
-   * mapped to info about direct dependence and what would
-   * be conflicting indirect dependencies if Lucene/Solr
-   * were to use transitive dependencies.
-   */
-  private Map<String,Dependency> directDependencies = new LinkedHashMap<>();
-
-  /**
-   * All /org/name keys found in ivy-ignore-conflicts.properties,
-   * mapped to the set of indirect dependency versions that will
-   * be ignored, i.e. not trigger a conflict.
-   */
-  private Map<String,HashSet<String>> ignoreConflictVersions = new HashMap<>();
-
-  private static class Dependency {
-    String org;
-    String name;
-    String directVersion;
-    String latestVersion;
-    boolean directlyReferenced = false;
-    LinkedHashMap<IvyNodeElement,Set<String>> conflictLocations = new LinkedHashMap<>(); // dependency path -> moduleNames
-    
-    Dependency(String org, String name, String directVersion) {
-      this.org = org;
-      this.name = name;
-      this.directVersion = directVersion;
-    }
-  }
-  
-  /**
-   * Adds a set of ivy.xml resources to check.
-   */
-  public void add(ResourceCollection rc) {
-    ivyXmlResources.add(rc);
-  }
-
-  public void setVerbose(boolean verbose) {
-    verboseLevel = (verbose ? Project.MSG_INFO : Project.MSG_VERBOSE);
-  }
-
-  public void setCentralizedVersionsFile(File file) {
-    centralizedVersionsFile = file;
-  }
-
-  public void setTopLevelIvySettingsFile(File file) {
-    topLevelIvySettingsFile = file;
-  }
-
-  public void setIvyResolutionCacheDir(File dir) {
-    ivyResolutionCacheDir = dir;
-  }
-  
-  public void setIvyLockStrategy(String strategy) {
-    this.ivyLockStrategy = strategy;
-  }
-
-  public void setCommonBuildDir(File file) {
-    commonBuildDir = file;
-  }
-  
-  public void setIgnoreConflictsFile(File file) {
-    ignoreConflictsFile = file;
-  }
-
-  /**
-   * Execute the task.
-   */
-  @Override
-  public void execute() throws BuildException {
-    log("Starting scan.", verboseLevel);
-    long start = System.currentTimeMillis();
-
-    setupIvy();
-
-    int numErrors = 0;
-    if ( ! verifySortedCoordinatesPropertiesFile(centralizedVersionsFile)) {
-      ++numErrors;
-    }
-    if ( ! verifySortedCoordinatesPropertiesFile(ignoreConflictsFile)) {
-      ++numErrors;
-    }
-    collectDirectDependencies();
-    if ( ! collectVersionConflictsToIgnore()) {
-      ++numErrors;
-    }
-
-    int numChecked = 0;
-
-    @SuppressWarnings("unchecked")
-    Iterator<Resource> iter = (Iterator<Resource>)ivyXmlResources.iterator();
-    while (iter.hasNext()) {
-      final Resource resource = iter.next();
-      if ( ! resource.isExists()) {
-        throw new BuildException("Resource does not exist: " + resource.getName());
-      }
-      if ( ! (resource instanceof FileResource)) {
-        throw new BuildException("Only filesystem resources are supported: " 
-            + resource.getName() + ", was: " + resource.getClass().getName());
-      }
-
-      File ivyXmlFile = ((FileResource)resource).getFile();
-      try {
-        if ( ! checkIvyXmlFile(ivyXmlFile)) {
-          ++numErrors;
-        }
-        if ( ! resolveTransitively(ivyXmlFile)) {
-          ++numErrors;
-        }
-        if ( ! findLatestConflictVersions()) {
-          ++numErrors;
-        }
-      } catch (Exception e) {
-        throw new BuildException("Exception reading file " + ivyXmlFile.getPath() + " - " + e.toString(), e);
-      }
-      ++numChecked;
-    }
-
-    log("Checking for orphans in " + centralizedVersionsFile.getName(), verboseLevel);
-    for (Map.Entry<String,Dependency> entry : directDependencies.entrySet()) {
-      String coordinateKey = entry.getKey();
-      if ( ! entry.getValue().directlyReferenced) {
-        log("ORPHAN coordinate key '" + coordinateKey + "' in " + centralizedVersionsFile.getName()
-            + " is not found in any " + IVY_XML_FILENAME + " file.",
-            Project.MSG_ERR);
-        ++numErrors;
-      }
-    }
-
-    int numConflicts = emitConflicts();
-
-    int messageLevel = numErrors > 0 ? Project.MSG_ERR : Project.MSG_INFO;
-    log("Checked that " + centralizedVersionsFile.getName() + " and " + ignoreConflictsFile.getName()
-        + " have lexically sorted '/org/name' keys and no duplicates or orphans.",
-        messageLevel);
-    log("Scanned " + numChecked + " " + IVY_XML_FILENAME + " files for rev=\"${/org/name}\" format.",
-        messageLevel);
-    log("Found " + numConflicts + " indirect dependency version conflicts.");
-    log(String.format(Locale.ROOT, "Completed in %.2fs., %d error(s).",
-                      (System.currentTimeMillis() - start) / 1000.0, numErrors),
-        messageLevel);
-
-    if (numConflicts > 0 || numErrors > 0) {
-      throw new BuildException("Lib versions check failed. Check the logs.");
-    }
-  }
-
-  private boolean findLatestConflictVersions() {
-    boolean success = true;
-    StringBuilder latestIvyXml = new StringBuilder();
-    latestIvyXml.append("<ivy-module version=\"2.0\">\n");
-    latestIvyXml.append("  <info organisation=\"org.apache.lucene\" module=\"core-tools-find-latest-revision\"/>\n");
-    latestIvyXml.append("  <configurations>\n");
-    latestIvyXml.append("    <conf name=\"default\" transitive=\"false\"/>\n");
-    latestIvyXml.append("  </configurations>\n");
-    latestIvyXml.append("  <dependencies>\n");
-    for (Map.Entry<String, Dependency> directDependency : directDependencies.entrySet()) {
-      Dependency dependency = directDependency.getValue();
-      if (dependency.conflictLocations.entrySet().isEmpty()) {
-        continue;
-      }
-      latestIvyXml.append("    <dependency org=\"");
-      latestIvyXml.append(dependency.org);
-      latestIvyXml.append("\" name=\"");
-      latestIvyXml.append(dependency.name);
-      latestIvyXml.append("\" rev=\"latest.release\" conf=\"default->*\"/>\n");
-    }
-    latestIvyXml.append("  </dependencies>\n");
-    latestIvyXml.append("</ivy-module>\n");
-    File buildDir = new File(commonBuildDir, "ivy-transitive-resolve");
-    if ( ! buildDir.exists() && ! buildDir.mkdirs()) {
-      throw new BuildException("Could not create temp directory " + buildDir.getPath());
-    }
-    File findLatestIvyXmlFile = new File(buildDir, "find.latest.conflicts.ivy.xml");
-    try {
-      try (Writer writer = new OutputStreamWriter(new FileOutputStream(findLatestIvyXmlFile), StandardCharsets.UTF_8)) {
-        writer.write(latestIvyXml.toString());
-      }
-      ResolveOptions options = new ResolveOptions();
-      options.setDownload(false);           // Download only module descriptors, not artifacts
-      options.setTransitive(false);         // Resolve only direct dependencies
-      options.setUseCacheOnly(false);       // Download the internet!
-      options.setOutputReport(false);       // Don't print to the console
-      options.setLog(LogOptions.LOG_QUIET); // Don't log to the console
-      options.setConfs(new String[] {"*"}); // Resolve all configurations
-      ResolveReport resolveReport = ivy.resolve(findLatestIvyXmlFile.toURI().toURL(), options);
-      IvyNodeElement root = IvyNodeElementAdapter.adapt(resolveReport);
-      for (IvyNodeElement element : root.getDependencies()) {
-        String coordinate = "/" + element.getOrganization() + "/" + element.getName();
-        Dependency dependency = directDependencies.get(coordinate);
-        if (null == dependency) {
-          log("ERROR: the following coordinate key does not appear in "
-              + centralizedVersionsFile.getName() + ": " + coordinate, Project.MSG_ERR);
-          success = false;
-        } else {
-          dependency.latestVersion = element.getRevision();
-        }
-      }
-    } catch (IOException e) {
-      log("Exception writing to " + findLatestIvyXmlFile.getPath() + ": " + e.toString(), Project.MSG_ERR);
-      success = false;
-    } catch (ParseException e) {
-      log("Exception parsing filename " + findLatestIvyXmlFile.getPath() + ": " + e.toString(), Project.MSG_ERR);
-      success = false;
-    }
-    return success;
-  }
-
-  /**
-   * Collects indirect dependency version conflicts to ignore 
-   * in ivy-ignore-conflicts.properties, and also checks for orphans
-   * (coordinates not included in ivy-versions.properties).
-   * 
-   * Returns true if no orphans are found.
-   */
-  private boolean collectVersionConflictsToIgnore() {
-    log("Checking for orphans in " + ignoreConflictsFile.getName(), verboseLevel);
-    boolean orphansFound = false;
-    InterpolatedProperties properties = new InterpolatedProperties();
-    try (InputStream inputStream = new FileInputStream(ignoreConflictsFile);
-         Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
-      properties.load(reader);
-    } catch (IOException e) {
-      throw new BuildException("Exception reading " + ignoreConflictsFile + ": " + e.toString(), e);
-    }
-    for (Object obj : properties.keySet()) {
-      String coordinate = (String)obj;
-      if (COORDINATE_KEY_PATTERN.matcher(coordinate).matches()) {
-        if ( ! directDependencies.containsKey(coordinate)) {
-          orphansFound = true;
-          log("ORPHAN coordinate key '" + coordinate + "' in " + ignoreConflictsFile.getName()
-                  + " is not found in " + centralizedVersionsFile.getName(),
-              Project.MSG_ERR);
-        } else {
-          String versionsToIgnore = properties.getProperty(coordinate);
-          List<String> ignore = Arrays.asList(versionsToIgnore.trim().split("\\s*,\\s*|\\s+"));
-          ignoreConflictVersions.put(coordinate, new HashSet<>(ignore));
-        }
-      }
-    }
-    return ! orphansFound;
-  }
-
-  private void collectDirectDependencies() {
-    InterpolatedProperties properties = new InterpolatedProperties();
-    try (InputStream inputStream = new FileInputStream(centralizedVersionsFile);
-         Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
-      properties.load(reader);
-    } catch (IOException e) {
-      throw new BuildException("Exception reading " + centralizedVersionsFile + ": " + e.toString(), e);
-    }
-    for (Object obj : properties.keySet()) {
-      String coordinate = (String)obj;
-      Matcher matcher = COORDINATE_KEY_PATTERN.matcher(coordinate);
-      if (matcher.matches()) {
-        String org = matcher.group(2);
-        String name = matcher.group(3);
-        String directVersion = properties.getProperty(coordinate);
-        Dependency dependency = new Dependency(org, name, directVersion);
-        directDependencies.put(coordinate, dependency);
-      }
-    }
-  }
-
-  /**
-   * Transitively resolves all dependencies in the given ivy.xml file,
-   * looking for indirect dependencies with versions that conflict
-   * with those of direct dependencies.  Dependency conflict when a
-   * direct dependency's version is older than that of an indirect
-   * dependency with the same /org/name.
-   * 
-   * Returns true if no version conflicts are found and no resolution
-   * errors occurred, false otherwise.
-   */
-  private boolean resolveTransitively(File ivyXmlFile) {
-    boolean success = true;
-
-    ResolveOptions options = new ResolveOptions();
-    options.setDownload(false);           // Download only module descriptors, not artifacts
-    options.setTransitive(true);          // Resolve transitively, if not already specified in the ivy.xml file
-    options.setUseCacheOnly(false);       // Download the internet!
-    options.setOutputReport(false);       // Don't print to the console
-    options.setLog(LogOptions.LOG_QUIET); // Don't log to the console
-    options.setConfs(new String[] {"*"}); // Resolve all configurations
-
-    // Rewrite the ivy.xml, replacing all 'transitive="false"' with 'transitive="true"'
-    // The Ivy API is file-based, so we have to write the result to the filesystem.
-    String moduleName = "unknown";
-    String ivyXmlContent = xmlToString(ivyXmlFile);
-    Matcher matcher = MODULE_NAME_PATTERN.matcher(ivyXmlContent);
-    if (matcher.find()) {
-      moduleName = matcher.group(1);
-    }
-    ivyXmlContent = ivyXmlContent.replaceAll("\\btransitive\\s*=\\s*[\"']false[\"']", "transitive=\"true\"");
-    File transitiveIvyXmlFile = null;
-    try {
-      File buildDir = new File(commonBuildDir, "ivy-transitive-resolve");
-      if ( ! buildDir.exists() && ! buildDir.mkdirs()) {
-        throw new BuildException("Could not create temp directory " + buildDir.getPath());
-      }
-      matcher = MODULE_DIRECTORY_PATTERN.matcher(ivyXmlFile.getCanonicalPath());
-      if ( ! matcher.matches()) {
-        throw new BuildException("Unknown ivy.xml module directory: " + ivyXmlFile.getCanonicalPath());
-      }
-      String moduleDirPrefix = matcher.group(1).replaceAll("[/\\\\]", ".");
-      transitiveIvyXmlFile = new File(buildDir, "transitive." + moduleDirPrefix + ".ivy.xml");
-      try (Writer writer = new OutputStreamWriter(new FileOutputStream(transitiveIvyXmlFile), StandardCharsets.UTF_8)) {
-        writer.write(ivyXmlContent);
-      }
-      ResolveReport resolveReport = ivy.resolve(transitiveIvyXmlFile.toURI().toURL(), options);
-      IvyNodeElement root = IvyNodeElementAdapter.adapt(resolveReport);
-      for (IvyNodeElement directDependency : root.getDependencies()) {
-        String coordinate = "/" + directDependency.getOrganization() + "/" + directDependency.getName();
-        Dependency dependency = directDependencies.get(coordinate);
-        if (null == dependency) {
-          log("ERROR: the following coordinate key does not appear in " 
-              + centralizedVersionsFile.getName() + ": " + coordinate);
-          success = false;
-        } else {
-          dependency.directlyReferenced = true;
-          if (collectConflicts(directDependency, directDependency, moduleName)) {
-            success = false;
-          }
-        }
-      }
-    } catch (ParseException | IOException e) {
-      if (null != transitiveIvyXmlFile) {
-        log("Exception reading " + transitiveIvyXmlFile.getPath() + ": " + e.toString());
-      }
-      success = false;
-    }
-    return success;
-  }
-
-  /**
-   * Recursively finds indirect dependencies that have a version conflict with a direct dependency.
-   * Returns true if one or more conflicts are found, false otherwise
-   */
-  private boolean collectConflicts(IvyNodeElement root, IvyNodeElement parent, String moduleName) {
-    boolean conflicts = false;
-    for (IvyNodeElement child : parent.getDependencies()) {
-      String coordinate = "/" + child.getOrganization() + "/" + child.getName();
-      Dependency dependency = directDependencies.get(coordinate);
-      if (null != dependency) { // Ignore this indirect dependency if it's not also a direct dependency
-        String indirectVersion = child.getRevision();
-        if (isConflict(coordinate, dependency.directVersion, indirectVersion)) {
-          conflicts = true;
-          Set<String> moduleNames = dependency.conflictLocations.get(root);
-          if (null == moduleNames) {
-            moduleNames = new HashSet<>();
-            dependency.conflictLocations.put(root, moduleNames);
-          }
-          moduleNames.add(moduleName);
-        }
-        conflicts |= collectConflicts(root, child, moduleName);
-      }
-    }
-    return conflicts;
-  }
-
-  /**
-   * Copy-pasted from Ivy's 
-   * org.apache.ivy.plugins.latest.LatestRevisionStrategy
-   * with minor modifications
-   */
-  private static final Map<String,Integer> SPECIAL_MEANINGS;
-  static {
-    SPECIAL_MEANINGS = new HashMap<>();
-    SPECIAL_MEANINGS.put("dev", -1);
-    SPECIAL_MEANINGS.put("rc", 1);
-    SPECIAL_MEANINGS.put("final", 2);
-  }
-
-  /**
-   * Copy-pasted from Ivy's 
-   * org.apache.ivy.plugins.latest.LatestRevisionStrategy.MridComparator
-   * with minor modifications
-   */
-  private static class LatestVersionComparator implements Comparator<String> {
-    @Override
-    public int compare(String rev1, String rev2) {
-      rev1 = rev1.replaceAll("([a-zA-Z])(\\d)", "$1.$2");
-      rev1 = rev1.replaceAll("(\\d)([a-zA-Z])", "$1.$2");
-      rev2 = rev2.replaceAll("([a-zA-Z])(\\d)", "$1.$2");
-      rev2 = rev2.replaceAll("(\\d)([a-zA-Z])", "$1.$2");
-
-      String[] parts1 = rev1.split("[-._+]");
-      String[] parts2 = rev2.split("[-._+]");
-
-      int i = 0;
-      for (; i < parts1.length && i < parts2.length; i++) {
-        if (parts1[i].equals(parts2[i])) {
-          continue;
-        }
-        boolean is1Number = isNumber(parts1[i]);
-        boolean is2Number = isNumber(parts2[i]);
-        if (is1Number && !is2Number) {
-          return 1;
-        }
-        if (is2Number && !is1Number) {
-          return -1;
-        }
-        if (is1Number && is2Number) {
-          return Long.valueOf(parts1[i]).compareTo(Long.valueOf(parts2[i]));
-        }
-        // both are strings, we compare them taking into account special meaning
-        Integer sm1 = SPECIAL_MEANINGS.get(parts1[i].toLowerCase(Locale.ROOT));
-        Integer sm2 = SPECIAL_MEANINGS.get(parts2[i].toLowerCase(Locale.ROOT));
-        if (sm1 != null) {
-          sm2 = sm2 == null ? 0 : sm2;
-          return sm1.compareTo(sm2);
-        }
-        if (sm2 != null) {
-          return Integer.valueOf(0).compareTo(sm2);
-        }
-        return parts1[i].compareTo(parts2[i]);
-      }
-      if (i < parts1.length) {
-        return isNumber(parts1[i]) ? 1 : -1;
-      }
-      if (i < parts2.length) {
-        return isNumber(parts2[i]) ? -1 : 1;
-      }
-      return 0;
-    }
-
-    private static final Pattern IS_NUMBER = Pattern.compile("\\d+");
-    private static boolean isNumber(String str) {
-      return IS_NUMBER.matcher(str).matches();
-    }
-  }
-  private static LatestVersionComparator LATEST_VERSION_COMPARATOR = new LatestVersionComparator();
-
-  /**
-   * Returns true if directVersion is less than indirectVersion, and 
-   * coordinate=indirectVersion is not present in ivy-ignore-conflicts.properties. 
-   */
-  private boolean isConflict(String coordinate, String directVersion, String indirectVersion) {
-    boolean isConflict = LATEST_VERSION_COMPARATOR.compare(directVersion, indirectVersion) < 0;
-    if (isConflict) {
-      Set<String> ignoredVersions = ignoreConflictVersions.get(coordinate);
-      if (null != ignoredVersions && ignoredVersions.contains(indirectVersion)) {
-        isConflict = false;
-      }
-    }
-    return isConflict;
-  }
-
-  /**
-   * Returns the number of direct dependencies in conflict with indirect
-   * dependencies.
-   */
-  private int emitConflicts() {
-    int conflicts = 0;
-    StringBuilder builder = new StringBuilder();
-    for (Map.Entry<String,Dependency> directDependency : directDependencies.entrySet()) {
-      String coordinate = directDependency.getKey();
-      Set<Map.Entry<IvyNodeElement,Set<String>>> entrySet
-          = directDependency.getValue().conflictLocations.entrySet();
-      if (entrySet.isEmpty()) {
-        continue;
-      }
-      ++conflicts;
-      Map.Entry<IvyNodeElement,Set<String>> first = entrySet.iterator().next();
-      int notPrinted = entrySet.size() - 1;
-      builder.append("VERSION CONFLICT: transitive dependency in module(s) ");
-      boolean isFirst = true;
-      for (String moduleName : first.getValue()) {
-        if (isFirst) {
-          isFirst = false;
-        } else {
-          builder.append(", ");
-        }
-        builder.append(moduleName);
-      }
-      builder.append(":\n");
-      IvyNodeElement element = first.getKey();
-      builder.append('/').append(element.getOrganization()).append('/').append(element.getName())
-             .append('=').append(element.getRevision()).append('\n');
-      emitConflict(builder, coordinate, first.getKey(), 1);
-        
-      if (notPrinted > 0) {
-        builder.append("... and ").append(notPrinted).append(" more\n");
-      }
-      builder.append("\n");
-    }
-    if (builder.length() > 0) {
-      log(builder.toString());
-    }
-    return conflicts;
-  }
-  
-  private boolean emitConflict(StringBuilder builder, String conflictCoordinate, IvyNodeElement parent, int depth) {
-    for (IvyNodeElement child : parent.getDependencies()) {
-      String indirectCoordinate = "/" + child.getOrganization() + "/" + child.getName();
-      if (conflictCoordinate.equals(indirectCoordinate)) {
-        Dependency dependency = directDependencies.get(conflictCoordinate);
-        String directVersion = dependency.directVersion;
-        if (isConflict(conflictCoordinate, directVersion, child.getRevision())) {
-          for (int i = 0 ; i < depth - 1 ; ++i) {
-            builder.append("    ");
-          }
-          builder.append("+-- ");
-          builder.append(indirectCoordinate).append("=").append(child.getRevision());
-          builder.append(" <<< Conflict (direct=").append(directVersion);
-          builder.append(", latest=").append(dependency.latestVersion).append(")\n");
-          return true;
-        }
-      } else if (hasConflicts(conflictCoordinate, child)) {
-        for (int i = 0 ; i < depth -1 ; ++i) {
-          builder.append("    ");
-        }
-        builder.append("+-- ");
-        builder.append(indirectCoordinate).append("=").append(child.getRevision()).append("\n");
-        if (emitConflict(builder, conflictCoordinate, child, depth + 1)) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-  
-  private boolean hasConflicts(String conflictCoordinate, IvyNodeElement parent) {
-    // the element itself will never be in conflict, since its coordinate is different
-    for (IvyNodeElement child : parent.getDependencies()) {
-      String indirectCoordinate = "/" + child.getOrganization() + "/" + child.getName();
-      if (conflictCoordinate.equals(indirectCoordinate)) {
-        Dependency dependency = directDependencies.get(conflictCoordinate);
-        if (isConflict(conflictCoordinate, dependency.directVersion, child.getRevision())) {
-          return true;
-        }
-      } else if (hasConflicts(conflictCoordinate, child)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  private String xmlToString(File ivyXmlFile) {
-    StringWriter writer = new StringWriter();
-    try {
-      StreamSource inputSource = new StreamSource(new FileInputStream(ivyXmlFile.getPath()));
-      Transformer serializer = TransformerFactory.newInstance().newTransformer();
-      serializer.transform(inputSource, new StreamResult(writer));
-    } catch (TransformerException | IOException e) {
-      throw new BuildException("Exception reading " + ivyXmlFile.getPath() + ": " + e.toString(), e);
-    }
-    return writer.toString();
-  }
-
-  private void setupIvy() {
-    IvySettings ivySettings = new IvySettings();
-    try {
-      ivySettings.setVariable("common.build.dir", commonBuildDir.getAbsolutePath());
-      ivySettings.setVariable("ivy.exclude.types", "source|javadoc");
-      ivySettings.setVariable("ivy.resolution-cache.dir", ivyResolutionCacheDir.getAbsolutePath());
-      ivySettings.setVariable("ivy.lock-strategy", ivyLockStrategy);
-      ivySettings.setVariable("ivysettings.xml", getProject().getProperty("ivysettings.xml")); // nested settings file
-      ivySettings.setBaseDir(commonBuildDir);
-      ivySettings.setDefaultConflictManager(new NoConflictManager());
-      ivy = Ivy.newInstance(ivySettings);
-      ivy.configure(topLevelIvySettingsFile);
-    } catch (Exception e) {
-      throw new BuildException("Exception reading " + topLevelIvySettingsFile.getPath() + ": " + e.toString(), e);
-    }
-  }
-
-  /**
-   * Returns true if the "/org/name" coordinate keys in the given
-   * properties file are lexically sorted and are not duplicates.
-   */
-  private boolean verifySortedCoordinatesPropertiesFile(File coordinatePropertiesFile) {
-    log("Checking for lexically sorted non-duplicated '/org/name' keys in: " + coordinatePropertiesFile, verboseLevel);
-    boolean success = true;
-    String line = null;
-    String currentKey = null;
-    String previousKey = null;
-    try (InputStream stream = new FileInputStream(coordinatePropertiesFile);
-         Reader reader = new InputStreamReader(stream, StandardCharsets.ISO_8859_1);
-         BufferedReader bufferedReader = new BufferedReader(reader)) {
-      while (null != (line = readLogicalPropertiesLine(bufferedReader))) {
-        final Matcher keyMatcher = COORDINATE_KEY_PATTERN.matcher(line);
-        if ( ! keyMatcher.lookingAt()) {
-          continue; // Ignore keys that don't look like "/org/name"
-        }
-        currentKey = keyMatcher.group(1);
-        if (null != previousKey) {
-          int comparison = currentKey.compareTo(previousKey);
-          if (0 == comparison) {
-            log("DUPLICATE coordinate key '" + currentKey + "' in " + coordinatePropertiesFile.getName(),
-                Project.MSG_ERR);
-            success = false;
-          } else if (comparison < 0) {
-            log("OUT-OF-ORDER coordinate key '" + currentKey + "' in " + coordinatePropertiesFile.getName(),
-                Project.MSG_ERR);
-            success = false;
-          }
-        }
-        previousKey = currentKey;
-      }
-    } catch (IOException e) {
-      throw new BuildException("Exception reading " + coordinatePropertiesFile.getPath() + ": " + e.toString(), e);
-    }
-    return success;
-  }
-
-  /**
-   * Builds up logical {@link java.util.Properties} lines, composed of one non-blank,
-   * non-comment initial line, either:
-   * 
-   * 1. without a non-escaped trailing slash; or
-   * 2. with a non-escaped trailing slash, followed by
-   *    zero or more lines with a non-escaped trailing slash, followed by
-   *    one or more lines without a non-escaped trailing slash
-   *
-   * All leading non-escaped whitespace and trailing non-escaped whitespace +
-   * non-escaped slash are trimmed from each line before concatenating.
-   * 
-   * After composing the logical line, escaped characters are un-escaped.
-   * 
-   * null is returned if there are no lines left to read. 
-   */
-  private String readLogicalPropertiesLine(BufferedReader reader) throws IOException {
-    final StringBuilder logicalLine = new StringBuilder();
-    String line;
-    do {
-      line = reader.readLine();
-      if (null == line) { 
-        return null;
-      }
-    } while (BLANK_OR_COMMENT_LINE_PATTERN.matcher(line).matches());
-
-    Matcher backslashMatcher = TRAILING_BACKSLASH_PATTERN.matcher(line); 
-    // Check for a non-escaped backslash
-    if (backslashMatcher.find() && 1 == (backslashMatcher.group(1).length() % 2)) {
-      final Matcher firstLineMatcher = TRAILING_WHITESPACE_BACKSLASH_PATTERN.matcher(line);
-      if (firstLineMatcher.matches()) {
-        logicalLine.append(firstLineMatcher.group(1)); // trim trailing backslash and any preceding whitespace
-      }
-      line = reader.readLine();
-      while (null != line
-             && (backslashMatcher = TRAILING_BACKSLASH_PATTERN.matcher(line)).find()
-             && 1 == (backslashMatcher.group(1).length() % 2)) {
-        // Trim leading whitespace, the trailing backslash and any preceding whitespace
-        final Matcher goodStuffMatcher = WHITESPACE_GOODSTUFF_WHITESPACE_BACKSLASH_PATTERN.matcher(line);
-        if (goodStuffMatcher.matches()) {
-          logicalLine.append(goodStuffMatcher.group(1));
-        }
-        line = reader.readLine();
-      }
-      if (null != line) {
-        // line can't have a non-escaped trailing backslash
-        final Matcher leadingWhitespaceMatcher = LEADING_WHITESPACE_PATTERN.matcher(line);
-        if (leadingWhitespaceMatcher.matches()) {
-          line = leadingWhitespaceMatcher.group(1); // trim leading whitespace
-        }
-        logicalLine.append(line);
-      }
-    } else {
-      logicalLine.append(line);
-    }
-    // trim non-escaped leading whitespace
-    final Matcher leadingWhitespaceMatcher = LEADING_WHITESPACE_PATTERN.matcher(logicalLine);
-    final CharSequence leadingWhitespaceStripped = leadingWhitespaceMatcher.matches()
-                                                 ? leadingWhitespaceMatcher.group(1)
-                                                 : logicalLine;
-
-    // unescape all chars in the logical line
-    StringBuilder output = new StringBuilder();
-    final int numChars = leadingWhitespaceStripped.length();
-    for (int pos = 0 ; pos < numChars - 1 ; ++pos) {
-      char ch = leadingWhitespaceStripped.charAt(pos);
-      if (ch == '\\') {
-        ch = leadingWhitespaceStripped.charAt(++pos);
-      }
-      output.append(ch);
-    }
-    if (numChars > 0) {
-      output.append(leadingWhitespaceStripped.charAt(numChars - 1));
-    }
-
-    return output.toString();
-  }
-
-  /**
-   * Check a single ivy.xml file for dependencies' versions in rev="${/org/name}"
-   * format.  Returns false if problems are found, true otherwise.
-   */
-  private boolean checkIvyXmlFile(File ivyXmlFile)
-      throws ParserConfigurationException, SAXException, IOException {
-    log("Scanning: " + ivyXmlFile.getPath(), verboseLevel);
-    SAXParser xmlReader = SAX_PARSER_FACTORY.newSAXParser();
-    DependencyRevChecker revChecker = new DependencyRevChecker(ivyXmlFile); 
-    xmlReader.parse(new InputSource(ivyXmlFile.getAbsolutePath()), revChecker);
-    return ! revChecker.fail;
-  }
-
-  private class DependencyRevChecker extends DefaultHandler {
-    private final File ivyXmlFile;
-    private final Stack<String> tags = new Stack<>();
-    
-    public boolean fail = false;
-
-    public DependencyRevChecker(File ivyXmlFile) {
-      this.ivyXmlFile = ivyXmlFile;
-    }
-
-    @Override
-    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
-      if (localName.equals("dependency") && insideDependenciesTag()) {
-        String org = attributes.getValue("org");
-        boolean foundAllAttributes = true;
-        if (null == org) {
-          log("MISSING 'org' attribute on <dependency> in " + ivyXmlFile.getPath(), Project.MSG_ERR);
-          fail = true;
-          foundAllAttributes = false;
-        }
-        String name = attributes.getValue("name");
-        if (null == name) {
-          log("MISSING 'name' attribute on <dependency> in " + ivyXmlFile.getPath(), Project.MSG_ERR);
-          fail = true;
-          foundAllAttributes = false;
-        }
-        String rev = attributes.getValue("rev");
-        if (null == rev) {
-          log("MISSING 'rev' attribute on <dependency> in " + ivyXmlFile.getPath(), Project.MSG_ERR);
-          fail = true;
-          foundAllAttributes = false;
-        }
-        if (foundAllAttributes) {
-          String coordinateKey = "/" + org + '/' + name;
-          String expectedRev = "${" + coordinateKey + '}';
-          if ( ! rev.equals(expectedRev)) {
-            log("BAD <dependency> 'rev' attribute value '" + rev + "' - expected '" + expectedRev + "'"
-                + " in " + ivyXmlFile.getPath(), Project.MSG_ERR);
-            fail = true;
-          }
-          if ( ! directDependencies.containsKey(coordinateKey)) {
-            log("MISSING key '" + coordinateKey + "' in " + centralizedVersionsFile.getPath(), Project.MSG_ERR);
-            fail = true;
-          }
-        }
-      }
-      tags.push(localName);
-    }
-
-    @Override
-    public void endElement (String uri, String localName, String qName) throws SAXException {
-      tags.pop();
-    }
-
-    private boolean insideDependenciesTag() {
-      return tags.size() == 2 && tags.get(0).equals("ivy-module") && tags.get(1).equals("dependencies");
-    }
-  }
-}
diff --git a/lucene/tools/src/java/org/apache/lucene/validation/LicenseCheckTask.java b/lucene/tools/src/java/org/apache/lucene/validation/LicenseCheckTask.java
deleted file mode 100644
index 96ef01d..0000000
--- a/lucene/tools/src/java/org/apache/lucene/validation/LicenseCheckTask.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.validation;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-import java.security.DigestInputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.types.Mapper;
-import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.ResourceCollection;
-import org.apache.tools.ant.types.resources.FileResource;
-import org.apache.tools.ant.types.resources.Resources;
-import org.apache.tools.ant.util.FileNameMapper;
-
-/**
- * An ANT task that verifies if JAR file have associated <code>LICENSE</code>,
- * <code>NOTICE</code>, and <code>sha1</code> files. 
- */
-public class LicenseCheckTask extends Task {
-
-  public final static String CHECKSUM_TYPE = "sha1";
-  private static final int CHECKSUM_BUFFER_SIZE = 8 * 1024;
-  private static final int CHECKSUM_BYTE_MASK = 0xFF;
-  private static final String FAILURE_MESSAGE = "License check failed. Check the logs.\n"
-      + "If you recently modified ivy-versions.properties or any module's ivy.xml,\n"
-      + "make sure you run \"ant clean-jars jar-checksums\" before running precommit.";
-
-  private Pattern skipRegexChecksum;
-  private boolean skipSnapshotsChecksum;
-  private boolean skipChecksum;
-  
-  /**
-   * All JAR files to check.
-   */
-  private Resources jarResources = new Resources();
-  
-  /**
-   * Directory containing licenses
-   */
-  private File licenseDirectory;
-
-  /**
-   * License file mapper.
-   */
-  private FileNameMapper licenseMapper;
-
-  /**
-   * A logging level associated with verbose logging.
-   */
-  private int verboseLevel = Project.MSG_VERBOSE;
-  
-  /**
-   * Failure flag.
-   */
-  private boolean failures;
-
-  /**
-   * Adds a set of JAR resources to check.
-   */
-  public void add(ResourceCollection rc) {
-    jarResources.add(rc);
-  }
-  
-  /**
-   * Adds a license mapper.
-   */
-  public void addConfiguredLicenseMapper(Mapper mapper) {
-    if (licenseMapper != null) {
-      throw new BuildException("Only one license mapper is allowed.");
-    }
-    this.licenseMapper = mapper.getImplementation();
-  }
-
-  public void setVerbose(boolean verbose) {
-    verboseLevel = (verbose ? Project.MSG_INFO : Project.MSG_VERBOSE);
-  }
-  
-  public void setLicenseDirectory(File file) {
-    licenseDirectory = file;
-  }
-  
-  public void setSkipSnapshotsChecksum(boolean skipSnapshotsChecksum) {
-    this.skipSnapshotsChecksum = skipSnapshotsChecksum;
-  }
-  
-  public void setSkipChecksum(boolean skipChecksum) {
-    this.skipChecksum = skipChecksum;
-  }
-
-  public void setSkipRegexChecksum(String skipRegexChecksum) {
-    try {
-      if (skipRegexChecksum != null && skipRegexChecksum.length() > 0) {
-        this.skipRegexChecksum = Pattern.compile(skipRegexChecksum);
-      }
-    } catch (PatternSyntaxException e) {
-      throw new BuildException("Unable to compile skipRegexChecksum pattern.  Reason: "
-          + e.getMessage() + " " + skipRegexChecksum, e);
-    }
-  }
-
-  /**
-   * Execute the task.
-   */
-  @Override
-  public void execute() throws BuildException {
-    if (licenseMapper == null) {
-      throw new BuildException("Expected an embedded <licenseMapper>.");
-    }
-
-    if (skipChecksum) {
-      log("Skipping checksum verification for dependencies", Project.MSG_INFO);
-    } else {
-      if (skipSnapshotsChecksum) {
-        log("Skipping checksum for SNAPSHOT dependencies", Project.MSG_INFO);
-      }
-
-      if (skipRegexChecksum != null) {
-        log("Skipping checksum for dependencies matching regex: " + skipRegexChecksum.pattern(),
-            Project.MSG_INFO);
-      }
-    }
-
-    jarResources.setProject(getProject());
-    processJars();
-
-    if (failures) {
-      throw new BuildException(FAILURE_MESSAGE);
-    }
-  }
-
-  /**
-   * Process all JARs.
-   */
-  private void processJars() {
-    log("Starting scan.", verboseLevel);
-    long start = System.currentTimeMillis();
-
-    @SuppressWarnings("unchecked")
-    Iterator<Resource> iter = (Iterator<Resource>) jarResources.iterator();
-    int checked = 0;
-    int errors = 0;
-    while (iter.hasNext()) {
-      final Resource r = iter.next();
-      if (!r.isExists()) { 
-        throw new BuildException("JAR resource does not exist: " + r.getName());
-      }
-      if (!(r instanceof FileResource)) {
-        throw new BuildException("Only filesystem resource are supported: " + r.getName()
-            + ", was: " + r.getClass().getName());
-      }
-
-      File jarFile = ((FileResource) r).getFile();
-      if (! checkJarFile(jarFile) ) {
-        errors++;
-      }
-      checked++;
-    }
-
-    log(String.format(Locale.ROOT, 
-        "Scanned %d JAR file(s) for licenses (in %.2fs.), %d error(s).",
-        checked, (System.currentTimeMillis() - start) / 1000.0, errors),
-        errors > 0 ? Project.MSG_ERR : Project.MSG_INFO);
-  }
-
-  /**
-   * Check a single JAR file.
-   */
-  private boolean checkJarFile(File jarFile) {
-    log("Scanning: " + jarFile.getPath(), verboseLevel);
-    
-    if (!skipChecksum) {
-      boolean skipDueToSnapshot = skipSnapshotsChecksum && jarFile.getName().contains("-SNAPSHOT");
-      if (!skipDueToSnapshot && !matchesRegexChecksum(jarFile, skipRegexChecksum)) {
-        // validate the jar matches against our expected hash
-        final File checksumFile = new File(licenseDirectory, jarFile.getName()
-            + "." + CHECKSUM_TYPE);
-        if (!(checksumFile.exists() && checksumFile.canRead())) {
-          log("MISSING " + CHECKSUM_TYPE + " checksum file for: "
-              + jarFile.getPath(), Project.MSG_ERR);
-          log("EXPECTED " + CHECKSUM_TYPE + " checksum file : "
-              + checksumFile.getPath(), Project.MSG_ERR);
-          this.failures = true;
-          return false;
-        } else {
-          final String expectedChecksum = readChecksumFile(checksumFile);
-          try {
-            final MessageDigest md = MessageDigest.getInstance(CHECKSUM_TYPE);
-            byte[] buf = new byte[CHECKSUM_BUFFER_SIZE];
-            try {
-              FileInputStream fis = new FileInputStream(jarFile);
-              try {
-                DigestInputStream dis = new DigestInputStream(fis, md);
-                try {
-                  while (dis.read(buf, 0, CHECKSUM_BUFFER_SIZE) != -1) {
-                    // NOOP
-                  }
-                } finally {
-                  dis.close();
-                }
-              } finally {
-                fis.close();
-              }
-            } catch (IOException ioe) {
-              throw new BuildException("IO error computing checksum of file: "
-                  + jarFile, ioe);
-            }
-            final byte[] checksumBytes = md.digest();
-            final String checksum = createChecksumString(checksumBytes);
-            if (!checksum.equals(expectedChecksum)) {
-              log("CHECKSUM FAILED for " + jarFile.getPath() + " (expected: \""
-                  + expectedChecksum + "\" was: \"" + checksum + "\")",
-                  Project.MSG_ERR);
-              this.failures = true;
-              return false;
-            }
-            
-          } catch (NoSuchAlgorithmException ae) {
-            throw new BuildException("Digest type " + CHECKSUM_TYPE
-                + " not supported by your JVM", ae);
-          }
-        }
-      } else if (skipDueToSnapshot) {
-        log("Skipping jar because it is a SNAPSHOT : "
-            + jarFile.getAbsolutePath(), Project.MSG_INFO);
-      } else {
-        log("Skipping jar because it matches regex pattern: "
-            + jarFile.getAbsolutePath() + " pattern: " + skipRegexChecksum.pattern(), Project.MSG_INFO);
-      }
-    }
-    
-    // Get the expected license path base from the mapper and search for license files.
-    Map<File, LicenseType> foundLicenses = new LinkedHashMap<>();
-    List<File> expectedLocations = new ArrayList<>();
-outer:
-    for (String mappedPath : licenseMapper.mapFileName(jarFile.getName())) {
-      for (LicenseType licenseType : LicenseType.values()) {
-        File licensePath = new File(licenseDirectory, mappedPath + licenseType.licenseFileSuffix());
-        if (licensePath.exists()) {
-          foundLicenses.put(licensePath, licenseType);
-          log(" FOUND " + licenseType.name() + " license at " + licensePath.getPath(), 
-              verboseLevel);
-          // We could continue scanning here to detect duplicate associations?
-          break outer;
-        } else {
-          expectedLocations.add(licensePath);
-        }
-      }
-    }
-
-    // Check for NOTICE files.
-    for (Map.Entry<File, LicenseType> e : foundLicenses.entrySet()) {
-      LicenseType license = e.getValue();
-      String licensePath = e.getKey().getName();
-      String baseName = licensePath.substring(
-          0, licensePath.length() - license.licenseFileSuffix().length());
-      File noticeFile = new File(licenseDirectory, baseName + license.noticeFileSuffix());
-
-      if (noticeFile.exists()) {
-        log(" FOUND NOTICE file at " + noticeFile.getAbsolutePath(), verboseLevel);
-      } else {
-        if (license.isNoticeRequired()) {
-            this.failures = true;
-            log("MISSING NOTICE for the license file:\n  "
-                + licensePath + "\n  Expected location below:\n  "
-                + noticeFile.getAbsolutePath(), Project.MSG_ERR);
-        }
-      }
-    }
-
-    // In case there is something missing, complain.
-    if (foundLicenses.isEmpty()) {
-      this.failures = true;
-      StringBuilder message = new StringBuilder();
-      message.append("MISSING LICENSE for the following file:\n  ").append(jarFile.getAbsolutePath()).append("\n  Expected locations below:\n");
-      for (File location : expectedLocations) {
-        message.append("  => ").append(location.getAbsolutePath()).append("\n");
-      }
-      log(message.toString(), Project.MSG_ERR);
-      return false;
-    }
-
-    return true;
-  }
-
-  private static final String createChecksumString(byte[] digest) {
-    StringBuilder checksum = new StringBuilder();
-    for (int i = 0; i < digest.length; i++) {
-      checksum.append(String.format(Locale.ROOT, "%02x", 
-                                    CHECKSUM_BYTE_MASK & digest[i]));
-    }
-    return checksum.toString();
-  }
-  private static final String readChecksumFile(File f) {
-    BufferedReader reader = null;
-    try {
-      reader = new BufferedReader(new InputStreamReader
-                                  (new FileInputStream(f), StandardCharsets.UTF_8));
-      try {
-        String checksum = reader.readLine();
-        if (null == checksum || 0 == checksum.length()) {
-          throw new BuildException("Failed to find checksum in file: " + f);
-        }
-        return checksum;
-      } finally {
-        reader.close();
-      }
-    } catch (IOException e) {
-      throw new BuildException("IO error reading checksum file: " + f, e);
-    }
-  }
-
-  private static final boolean matchesRegexChecksum(File jarFile, Pattern skipRegexChecksum) {
-    if (skipRegexChecksum == null) {
-      return false;
-    }
-    Matcher m = skipRegexChecksum.matcher(jarFile.getName());
-    return m.matches();
-  }
-}
diff --git a/lucene/tools/src/java/org/apache/lucene/validation/LicenseType.java b/lucene/tools/src/java/org/apache/lucene/validation/LicenseType.java
deleted file mode 100644
index 2359382..0000000
--- a/lucene/tools/src/java/org/apache/lucene/validation/LicenseType.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.validation;
-
-
-/**
- * A list of accepted licenses.  See also http://www.apache.org/legal/3party.html
- *
- **/
-public enum LicenseType {
-  ASL("Apache Software License 2.0", true),
-  BSD("Berkeley Software Distribution", true),
-  BSD_LIKE("BSD like license", true),//BSD like just means someone has taken the BSD license and put in their name, copyright, or it's a very similar license.
-  CDDL("Common Development and Distribution License", false),
-  CPL("Common Public License", true),
-  EPL("Eclipse Public License Version 1.0", false),
-  MIT("Massachusetts Institute of Tech. License", false),
-  MPL("Mozilla Public License", false), //NOT SURE on the required notice
-  PD("Public Domain", false),
-  //SUNBCLA("Sun Binary Code License Agreement"),
-  SUN("Sun Open Source License", false),
-  COMPOUND("Compound license (see NOTICE).", true),
-  FAKE("FAKE license - not needed", false);
-
-  private String display;
-  private boolean noticeRequired;
-
-  LicenseType(String display, boolean noticeRequired) {
-    this.display = display;
-    this.noticeRequired = noticeRequired;
-  }
-
-  public boolean isNoticeRequired() {
-    return noticeRequired;
-  }
-
-  public String getDisplay() {
-    return display;
-  }
-
-  public String toString() {
-    return "LicenseType{" +
-            "display='" + display + '\'' +
-            '}';
-  }
-
-  /**
-   * Expected license file suffix for a given license type.
-   */
-  public String licenseFileSuffix() {
-    return "-LICENSE-" + this.name() + ".txt";
-  }
-
-  /**
-   * Expected notice file suffix for a given license type.
-   */
-  public String noticeFileSuffix() {
-    return "-NOTICE.txt";
-  }
-}
-
diff --git a/lucene/tools/src/java/org/apache/lucene/validation/ivyde/IvyNodeElement.java b/lucene/tools/src/java/org/apache/lucene/validation/ivyde/IvyNodeElement.java
deleted file mode 100644
index 287527e..0000000
--- a/lucene/tools/src/java/org/apache/lucene/validation/ivyde/IvyNodeElement.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.validation.ivyde;
-
-import org.apache.ivy.core.module.id.ModuleRevisionId;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * Assists in the further separation of concerns between the view and the Ivy resolve report. The view looks at the
- * IvyNode in a unique way that can lead to expensive operations if we do not achieve this separation.
- * 
- * This class is copied from org/apache/ivyde/eclipse/resolvevisualizer/model/IvyNodeElement.java at 
- * https://svn.apache.org/repos/asf/ant/ivy/ivyde/trunk/org.apache.ivyde.eclipse.resolvevisualizer/src/
- *
- * Changes include: uncommenting generics and converting to diamond operators where appropriate;
- * removing unnecessary casts; removing javadoc tags with no description; and adding a hashCode() implementation.
- */
-public class IvyNodeElement {
-  private ModuleRevisionId moduleRevisionId;
-  private boolean evicted = false;
-  private int depth = Integer.MAX_VALUE / 10;
-  private Collection<IvyNodeElement> dependencies = new HashSet<>();
-  private Collection<IvyNodeElement> callers = new HashSet<>();
-  private Collection<IvyNodeElement> conflicts = new HashSet<>();
-
-  /**
-   * The caller configurations that caused this node to be reached in the resolution, grouped by caller.
-   */
-  private Map<IvyNodeElement,String[]>callerConfigurationMap = new HashMap<>();
-
-  /**
-   * We try to avoid building the list of this nodes deep dependencies by storing them in this cache by depth level.
-   */
-  private IvyNodeElement[] deepDependencyCache;
-  
-  @Override
-  public boolean equals(Object obj) {
-    if (obj instanceof IvyNodeElement) {
-      IvyNodeElement elem = (IvyNodeElement) obj;
-      if (elem.getOrganization().equals(getOrganization()) && elem.getName().equals(getName())
-          && elem.getRevision().equals(getRevision()))
-        return true;
-    }
-    return false;
-  }
-  
-  @Override
-  public int hashCode() {
-    int result = 1;
-    result = result * 31 + (null == getOrganization() ? 0 : getOrganization().hashCode());
-    result = result * 31 + (null == getName() ? 0 : getName().hashCode());
-    result = result * 31 + (null == getRevision() ? 0 : getRevision().hashCode());
-    return result;
-  }
-
-  public IvyNodeElement[] getDependencies() {
-    return dependencies.toArray(new IvyNodeElement[dependencies.size()]);
-  }
-
-  /**
-   * Recursive dependency retrieval
-   *
-   * @return The array of nodes that represents a node's immediate and transitive dependencies down to an arbitrary
-   *         depth.
-   */
-  public IvyNodeElement[] getDeepDependencies() {
-    if (deepDependencyCache == null) {
-      Collection<IvyNodeElement> deepDependencies = getDeepDependencies(this);
-      deepDependencyCache = deepDependencies.toArray(new IvyNodeElement[deepDependencies.size()]);
-    }
-    return deepDependencyCache;
-  }
-
-  /**
-   * Recursive dependency retrieval
-   */
-  private Collection<IvyNodeElement> getDeepDependencies(IvyNodeElement node) {
-    Collection<IvyNodeElement> deepDependencies = new HashSet<>();
-    deepDependencies.add(node);
-
-    IvyNodeElement[] directDependencies = node.getDependencies();
-    for (int i = 0; i < directDependencies.length; i++) {
-      deepDependencies.addAll(getDeepDependencies(directDependencies[i]));
-    }
-
-    return deepDependencies;
-  }
-
-  /**
-   * @return An array of configurations by which this module was resolved
-   */
-  public String[] getCallerConfigurations(IvyNodeElement caller) {
-    return callerConfigurationMap.get(caller);
-  }
-
-  public void setCallerConfigurations(IvyNodeElement caller, String[] configurations) {
-    callerConfigurationMap.put(caller, configurations);
-  }
-
-  public String getOrganization() {
-    return moduleRevisionId.getOrganisation();
-  }
-
-  public String getName() {
-    return moduleRevisionId.getName();
-  }
-
-  public String getRevision() {
-    return moduleRevisionId.getRevision();
-  }
-
-  public boolean isEvicted() {
-    return evicted;
-  }
-
-  public void setEvicted(boolean evicted) {
-    this.evicted = evicted;
-  }
-
-  public int getDepth() {
-    return depth;
-  }
-
-  /**
-   * Set this node's depth and recursively update the node's children to relative to the new value.
-   */
-  public void setDepth(int depth) {
-    this.depth = depth;
-    for (Iterator<IvyNodeElement> iter = dependencies.iterator(); iter.hasNext();) {
-      IvyNodeElement dependency = iter.next();
-      dependency.setDepth(depth + 1);
-    }
-  }
-
-  public IvyNodeElement[] getConflicts() {
-    return conflicts.toArray(new IvyNodeElement[conflicts.size()]);
-  }
-
-  public void setConflicts(Collection<IvyNodeElement> conflicts) {
-    this.conflicts = conflicts;
-  }
-
-  public ModuleRevisionId getModuleRevisionId() {
-    return moduleRevisionId;
-  }
-
-  public void setModuleRevisionId(ModuleRevisionId moduleRevisionId) {
-    this.moduleRevisionId = moduleRevisionId;
-  }
-
-  public void addCaller(IvyNodeElement caller) {
-    callers.add(caller);
-    caller.dependencies.add(this);
-  }
-
-  public IvyNodeElement[] getCallers() {
-    return callers.toArray(new IvyNodeElement[callers.size()]);
-  }
-}
\ No newline at end of file
diff --git a/lucene/tools/src/java/org/apache/lucene/validation/ivyde/IvyNodeElementAdapter.java b/lucene/tools/src/java/org/apache/lucene/validation/ivyde/IvyNodeElementAdapter.java
deleted file mode 100644
index c754dd4..0000000
--- a/lucene/tools/src/java/org/apache/lucene/validation/ivyde/IvyNodeElementAdapter.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.validation.ivyde;
-
-import org.apache.ivy.core.module.id.ModuleId;
-import org.apache.ivy.core.module.id.ModuleRevisionId;
-import org.apache.ivy.core.report.ResolveReport;
-import org.apache.ivy.core.resolve.IvyNode;
-import org.apache.ivy.core.resolve.IvyNodeCallers;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class is copied from org/apache/ivyde/eclipse/resolvevisualizer/model/IvyNodeElementAdapter.java at 
- * https://svn.apache.org/repos/asf/ant/ivy/ivyde/trunk/org.apache.ivyde.eclipse.resolvevisualizer/src/
- * 
- * Changes include: uncommenting generics and converting to diamond operators where appropriate;
- * removing unnecessary casts; and removing javadoc tags with no description.
- */
-public class IvyNodeElementAdapter {
-  /**
-   * Adapt all dependencies and evictions from the ResolveReport.
-   * @return the root node adapted from the ResolveReport
-   */
-  public static IvyNodeElement adapt(ResolveReport report) {
-    Map<ModuleRevisionId,IvyNodeElement> resolvedNodes = new HashMap<>();
-
-    IvyNodeElement root = new IvyNodeElement();
-    root.setModuleRevisionId(report.getModuleDescriptor().getModuleRevisionId());
-    resolvedNodes.put(report.getModuleDescriptor().getModuleRevisionId(), root);
-
-    @SuppressWarnings("unchecked") List<IvyNode> dependencies = report.getDependencies();
-
-    // First pass - build the map of resolved nodes by revision id
-    for (Iterator<IvyNode> iter = dependencies.iterator(); iter.hasNext();) {
-      IvyNode node = iter.next();
-      if (node.getAllEvictingNodes() != null) {
-        // Nodes that are evicted as a result of conf inheritance still appear
-        // as dependencies, but with eviction data. They also appear as evictions.
-        // We map them as evictions rather than dependencies.
-        continue;
-      }
-      IvyNodeElement nodeElement = new IvyNodeElement();
-      nodeElement.setModuleRevisionId(node.getResolvedId());
-      resolvedNodes.put(node.getResolvedId(), nodeElement);
-    }
-
-    // Second pass - establish relationships between the resolved nodes
-    for (Iterator<IvyNode> iter = dependencies.iterator(); iter.hasNext();) {
-      IvyNode node = iter.next();
-      if (node.getAllEvictingNodes() != null) {
-        continue; // see note above
-      }
-
-      IvyNodeElement nodeElement = resolvedNodes.get(node.getResolvedId());
-      IvyNodeCallers.Caller[] callers = node.getAllRealCallers();
-      for (int i = 0; i < callers.length; i++) {
-        IvyNodeElement caller = resolvedNodes.get(callers[i].getModuleRevisionId());
-        if (caller != null) {
-          nodeElement.addCaller(caller);
-          nodeElement.setCallerConfigurations(caller, callers[i].getCallerConfigurations());
-        }
-      }
-    }
-
-    IvyNode[] evictions = report.getEvictedNodes();
-    for (int i = 0; i < evictions.length; i++) {
-      IvyNode eviction = evictions[i];
-      IvyNodeElement evictionElement = new IvyNodeElement();
-      evictionElement.setModuleRevisionId(eviction.getResolvedId());
-      evictionElement.setEvicted(true);
-
-      IvyNodeCallers.Caller[] callers = eviction.getAllCallers();
-      for (int j = 0; j < callers.length; j++) {
-        IvyNodeElement caller = resolvedNodes.get(callers[j].getModuleRevisionId());
-        if (caller != null) {
-          evictionElement.addCaller(caller);
-          evictionElement.setCallerConfigurations(caller, callers[j].getCallerConfigurations());
-        }
-      }
-    }
-
-    // Recursively set depth starting at root
-    root.setDepth(0);
-    findConflictsBeneathNode(root);
-
-    return root;
-  }
-
-  /**
-   * Derives configuration conflicts that exist between node and all of its descendant dependencies.
-   */
-  private static void findConflictsBeneathNode(IvyNodeElement node) {
-    // Derive conflicts
-    Map<ModuleId,Collection<IvyNodeElement>> moduleRevisionMap = new HashMap<>();
-    IvyNodeElement[] deepDependencies = node.getDeepDependencies();
-    for (int i = 0; i < deepDependencies.length; i++) {
-      if (deepDependencies[i].isEvicted())
-        continue;
-
-      ModuleId moduleId = deepDependencies[i].getModuleRevisionId().getModuleId();
-      if (moduleRevisionMap.containsKey(moduleId)) {
-        Collection<IvyNodeElement> conflicts = moduleRevisionMap.get(moduleId);
-        conflicts.add(deepDependencies[i]);
-        for (Iterator<IvyNodeElement> iter = conflicts.iterator(); iter.hasNext();) {
-          IvyNodeElement conflict = iter.next();
-          conflict.setConflicts(conflicts);
-        }
-      } else {
-        List<IvyNodeElement> immutableMatchingSet = Arrays.asList(deepDependencies[i]);
-        moduleRevisionMap.put(moduleId, new HashSet<>(immutableMatchingSet));
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/solr/contrib/prometheus-exporter/build.gradle b/solr/contrib/prometheus-exporter/build.gradle
index 13a9748..6ff390f 100644
--- a/solr/contrib/prometheus-exporter/build.gradle
+++ b/solr/contrib/prometheus-exporter/build.gradle
@@ -37,11 +37,3 @@ dependencies {
 
   testImplementation project(':solr:test-framework')
 }
-
-// Add two folders to default packaging.
-assemblePackaging {
-  from(projectDir, {
-    include "bin/**"
-    include "conf/**"
-  })
-}
\ No newline at end of file


[lucene-solr] 32/39: LUCENE-9512: Move LockFactory stress test to be a unit/integration test (#1842)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 9b83be52f9e1a202859e09de7f9f2eca91dd98f1
Author: Uwe Schindler <us...@apache.org>
AuthorDate: Wed Sep 9 18:42:30 2020 +0200

    LUCENE-9512: Move LockFactory stress test to be a unit/integration test (#1842)
    
    Co-authored-by: Dawid Weiss <da...@carrotsearch.com>
---
 gradle/testing/randomization/policies/tests.policy |   3 +
 .../org/apache/lucene/store/LockStressTest.java    |  43 +++++----
 .../org/apache/lucene/store/LockVerifyServer.java  |  44 ++++-----
 .../apache/lucene/store/VerifyingLockFactory.java  |   6 +-
 .../lucene/store/TestStressLockFactories.java      | 104 +++++++++++++++++++++
 5 files changed, 157 insertions(+), 43 deletions(-)

diff --git a/gradle/testing/randomization/policies/tests.policy b/gradle/testing/randomization/policies/tests.policy
index 8dedb3b..c718411 100644
--- a/gradle/testing/randomization/policies/tests.policy
+++ b/gradle/testing/randomization/policies/tests.policy
@@ -64,6 +64,9 @@ grant {
   permission java.lang.RuntimePermission "getClassLoader";
   permission java.lang.RuntimePermission "setContextClassLoader";
 
+  // TestLockFactoriesMultiJVM opens a random port on 127.0.0.1 (port 0 = ephemeral port range):
+  permission java.net.SocketPermission "127.0.0.1:0", "accept,listen,resolve";
+
   // read access to all system properties:
   permission java.util.PropertyPermission "*", "read";
   // write access to only these:
diff --git a/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java b/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java
index b319df4..38997a5 100644
--- a/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java
+++ b/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java
@@ -30,7 +30,7 @@ import org.apache.lucene.util.SuppressForbidden;
 
 /**
  * Simple standalone tool that forever acquires and releases a
- * lock using a specific LockFactory.  Run without any args
+ * lock using a specific {@link LockFactory}.  Run without any args
  * to see usage.
  *
  * @see VerifyingLockFactory
@@ -38,11 +38,9 @@ import org.apache.lucene.util.SuppressForbidden;
  */ 
 
 public class LockStressTest {
-  
   static final String LOCK_FILE_NAME = "test.lock";
-
+  
   @SuppressForbidden(reason = "System.out required: command line tool")
-  @SuppressWarnings("try")
   public static void main(String[] args) throws Exception {
     if (args.length != 7) {
       System.out.println("Usage: java org.apache.lucene.store.LockStressTest myID verifierHost verifierPort lockFactoryClassName lockDirName sleepTimeMS count\n" +
@@ -65,12 +63,6 @@ public class LockStressTest {
 
     int arg = 0;
     final int myID = Integer.parseInt(args[arg++]);
-
-    if (myID < 0 || myID > 255) {
-      System.out.println("myID must be a unique int 0..255");
-      System.exit(1);
-    }
-
     final String verifierHost = args[arg++];
     final int verifierPort = Integer.parseInt(args[arg++]);
     final String lockFactoryClassName = args[arg++];
@@ -78,8 +70,21 @@ public class LockStressTest {
     final int sleepTimeMS = Integer.parseInt(args[arg++]);
     final int count = Integer.parseInt(args[arg++]);
 
+    int exitCode = run(myID, verifierHost, verifierPort, lockFactoryClassName, lockDirPath, sleepTimeMS, count);
+    System.exit(exitCode);
+  }
+
+  @SuppressForbidden(reason = "System.out required: command line tool")
+  @SuppressWarnings("try")
+  private static int run(int myID, String verifierHost, int verifierPort, String lockFactoryClassName,
+                        Path lockDirPath, int sleepTimeMS, int count) throws IOException, InterruptedException {
+    if (myID < 0 || myID > 255) {
+      System.out.println("myID must be a unique int 0..255");
+      return 1;
+    }
+
     final LockFactory lockFactory = getNewLockFactory(lockFactoryClassName);
-    // we test the lock factory directly, so we don't need it on the directory itsself (the directory is just for testing)
+    // we test the lock factory directly, so we don't need it on the directory itself (the directory is just for testing)
     final FSDirectory lockDir = new NIOFSDirectory(lockDirPath, NoLockFactory.INSTANCE);
     final InetSocketAddress addr = new InetSocketAddress(verifierHost, verifierPort);
     System.out.println("Connecting to server " + addr +
@@ -89,17 +94,17 @@ public class LockStressTest {
       socket.connect(addr, 500);
       final OutputStream out = socket.getOutputStream();
       final InputStream in = socket.getInputStream();
-      
+
       out.write(myID);
       out.flush();
       LockFactory verifyLF = new VerifyingLockFactory(lockFactory, in, out);
       final Random rnd = new Random();
-      
+
       // wait for starting gun
-      if (in.read() != 43) {
+      if (in.read() != LockVerifyServer.START_GUN_SIGNAL) {
         throw new IOException("Protocol violation");
       }
-      
+
       for (int i = 0; i < count; i++) {
         try (final Lock l = verifyLF.obtainLock(lockDir, LOCK_FILE_NAME)) {
           if (rnd.nextInt(10) == 0) {
@@ -120,15 +125,15 @@ public class LockStressTest {
         if (i % 500 == 0) {
           System.out.println((i * 100. / count) + "% done.");
         }
-        
+
         Thread.sleep(sleepTimeMS);
-      } 
+      }
     }
-    
+
     System.out.println("Finished " + count + " tries.");
+    return 0;
   }
 
-
   private static FSLockFactory getNewLockFactory(String lockFactoryClassName) throws IOException {
     // try to get static INSTANCE field of class
     try {
diff --git a/lucene/core/src/java/org/apache/lucene/store/LockVerifyServer.java b/lucene/core/src/java/org/apache/lucene/store/LockVerifyServer.java
index 3ce0c06..c9d77bb 100644
--- a/lucene/core/src/java/org/apache/lucene/store/LockVerifyServer.java
+++ b/lucene/core/src/java/org/apache/lucene/store/LockVerifyServer.java
@@ -24,6 +24,7 @@ import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.util.concurrent.CountDownLatch;
+import java.util.function.Consumer;
 
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.SuppressForbidden;
@@ -38,20 +39,12 @@ import org.apache.lucene.util.SuppressForbidden;
  * @see LockStressTest
  */
 
+@SuppressForbidden(reason = "System.out required: command line tool")
 public class LockVerifyServer {
+  public static final int START_GUN_SIGNAL = 43;
 
-  @SuppressForbidden(reason = "System.out required: command line tool")
-  public static void main(String[] args) throws Exception {
-
-    if (args.length != 2) {
-      System.out.println("Usage: java org.apache.lucene.store.LockVerifyServer bindToIp clients\n");
-      System.exit(1);
-    }
-
-    int arg = 0;
-    final String hostname = args[arg++];
-    final int maxClients = Integer.parseInt(args[arg++]);
-
+  // method pkg-private for tests
+  static void run(String hostname, int maxClients, Consumer<InetSocketAddress> startClients) throws Exception {
     try (final ServerSocket s = new ServerSocket()) {
       s.setReuseAddress(true);
       s.setSoTimeout(30000); // initially 30 secs to give clients enough time to startup
@@ -59,8 +52,8 @@ public class LockVerifyServer {
       final InetSocketAddress localAddr = (InetSocketAddress) s.getLocalSocketAddress();
       System.out.println("Listening on " + localAddr + "...");
       
-      // we set the port as a sysprop, so the ANT task can read it. For that to work, this server must run in-process:
-      System.setProperty("lockverifyserver.port", Integer.toString(localAddr.getPort()));
+      // callback only for the test to start the clients:
+      startClients.accept(localAddr);
       
       final Object localLock = new Object();
       final int[] lockedID = new int[1];
@@ -80,22 +73,22 @@ public class LockVerifyServer {
               }
               
               startingGun.await();
-              os.write(43);
+              os.write(START_GUN_SIGNAL);
               os.flush();
               
-              while(true) {
+              while (true) {
                 final int command = in.read();
                 if (command < 0) {
                   return; // closed
                 }
                 
-                synchronized(localLock) {
+                synchronized (localLock) {
                   final int currentLock = lockedID[0];
                   if (currentLock == -2) {
                     return; // another thread got error, so we exit, too!
                   }
                   switch (command) {
-                    case 1:
+                    case VerifyingLockFactory.MSG_LOCK_ACQUIRED:
                       // Locked
                       if (currentLock != -1) {
                         lockedID[0] = -2;
@@ -103,7 +96,7 @@ public class LockVerifyServer {
                       }
                       lockedID[0] = id;
                       break;
-                    case 0:
+                    case VerifyingLockFactory.MSG_LOCK_RELEASED:
                       // Unlocked
                       if (currentLock != id) {
                         lockedID[0] = -2;
@@ -138,11 +131,18 @@ public class LockVerifyServer {
       for (Thread t : threads) {
         t.join();
       }
-      
-      // cleanup sysprop
-      System.clearProperty("lockverifyserver.port");
 
       System.out.println("Server terminated.");
     }
   }
+
+  public static void main(String[] args) throws Exception {
+    if (args.length != 2) {
+      System.out.println("Usage: java org.apache.lucene.store.LockVerifyServer bindToIp clients\n");
+      System.exit(1);
+    }
+
+    run(args[0], Integer.parseInt(args[1]), addr -> {});
+  }
+  
 }
diff --git a/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java b/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java
index 6a7214b..1b9ce23 100644
--- a/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java
+++ b/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java
@@ -36,6 +36,8 @@ import java.io.OutputStream;
  */
 
 public final class VerifyingLockFactory extends LockFactory {
+  public static final int MSG_LOCK_RELEASED = 0;
+  public static final int MSG_LOCK_ACQUIRED = 1;
 
   final LockFactory lf;
   final InputStream in;
@@ -46,7 +48,7 @@ public final class VerifyingLockFactory extends LockFactory {
 
     public CheckedLock(Lock lock) throws IOException {
       this.lock = lock;
-      verify((byte) 1);
+      verify((byte) MSG_LOCK_ACQUIRED);
     }
 
     @Override
@@ -58,7 +60,7 @@ public final class VerifyingLockFactory extends LockFactory {
     public void close() throws IOException {
       try (Lock l = lock) {
         l.ensureValid();
-        verify((byte) 0);
+        verify((byte) MSG_LOCK_RELEASED);
       }
     }
 
diff --git a/lucene/core/src/test/org/apache/lucene/store/TestStressLockFactories.java b/lucene/core/src/test/org/apache/lucene/store/TestStressLockFactories.java
new file mode 100644
index 0000000..a55aa2d
--- /dev/null
+++ b/lucene/core/src/test/org/apache/lucene/store/TestStressLockFactories.java
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.store;
+
+import java.io.IOException;
+import java.lang.ProcessBuilder.Redirect;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.SuppressForbidden;
+
+@LuceneTestCase.SuppressFileSystems("*")
+public class TestStressLockFactories extends LuceneTestCase {
+  
+  @SuppressForbidden(reason = "ProcessBuilder only allows to redirect to java.io.File")
+  private static final ProcessBuilder applyRedirection(ProcessBuilder pb, int client, Path dir) {
+    if (VERBOSE) {
+      return pb.inheritIO();
+    } else {
+      return pb
+        .redirectError(dir.resolve("err-" + client + ".txt").toFile())
+        .redirectOutput(dir.resolve("out-" + client + ".txt").toFile())
+        .redirectInput(Redirect.INHERIT);
+    }
+  }
+  
+  private void runImpl(Class<? extends LockFactory> impl) throws Exception {
+    final int clients = TEST_NIGHTLY ? 5 : 2;
+    final String host = "127.0.0.1";
+    final int delay = 1;
+    final int rounds = (TEST_NIGHTLY ? 30000 : 500) * RANDOM_MULTIPLIER;
+    
+    final Path dir = createTempDir(impl.getSimpleName());
+    
+    final List<Process> processes = new ArrayList<>(clients);
+
+    LockVerifyServer.run(host, clients, addr -> {
+      // spawn clients as separate Java processes
+      for (int i = 0; i < clients; i++) {
+        try {
+          processes.add(applyRedirection(new ProcessBuilder(
+              Paths.get(System.getProperty("java.home"), "bin", "java").toString(),
+              "-Xmx32M",
+              "-cp",
+              System.getProperty("java.class.path"),
+              LockStressTest.class.getName(),
+              Integer.toString(i),
+              addr.getHostString(),
+              Integer.toString(addr.getPort()),
+              impl.getName(),
+              dir.toString(),
+              Integer.toString(delay),
+              Integer.toString(rounds)
+            ), i, dir).start());
+        } catch (IOException ioe) {
+          throw new AssertionError("Failed to start child process.", ioe);
+        }
+      }
+    });
+     
+    // wait for all processes to exit...
+    try {
+      for (Process p : processes) {
+        if (p.waitFor(15, TimeUnit.SECONDS)) {
+          assertEquals("Process " + p.pid() + " died abnormally?", 0, p.waitFor());
+        }
+      }
+    } finally {
+      // kill all processes, which are still alive.
+      for (Process p : processes) {
+        if (p.isAlive()) {
+          p.destroyForcibly().waitFor();
+        }
+      }
+    }
+  }
+  
+  public void testNativeFSLockFactory() throws Exception {
+    runImpl(NativeFSLockFactory.class);
+  }
+
+  public void testSimpleFSLockFactory() throws Exception {
+    runImpl(SimpleFSLockFactory.class);
+  }
+
+}


[lucene-solr] 25/39: Cleanup remaining scripts to use script-relative resource location.

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit ff33a6393dca2a212546a2323daad1e59e0e1738
Author: Dawid Weiss <dw...@apache.org>
AuthorDate: Mon Aug 31 15:35:14 2020 +0200

    Cleanup remaining scripts to use script-relative resource location.
---
 gradle/documentation/render-javadoc.gradle          | 21 +++++++++++++--------
 gradle/testing/defaults-tests.gradle                |  3 ++-
 gradle/testing/randomization.gradle                 |  8 +++++---
 .../policies/replicator-tests.policy                |  0
 .../{ => randomization}/policies/solr-tests.policy  |  0
 .../{ => randomization}/policies/tests.policy       |  0
 gradle/validation/ecj-lint.gradle                   |  4 +++-
 gradle/validation/forbidden-apis.gradle             |  8 +++++---
 gradle/validation/owasp-dependency-check.gradle     |  4 +++-
 9 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/gradle/documentation/render-javadoc.gradle b/gradle/documentation/render-javadoc.gradle
index 46bb867..57892c2 100644
--- a/gradle/documentation/render-javadoc.gradle
+++ b/gradle/documentation/render-javadoc.gradle
@@ -20,6 +20,8 @@ import javax.annotation.Nullable
 // generate javadocs by calling javadoc tool
 // see https://docs.oracle.com/en/java/javase/11/tools/javadoc.html
 
+def resources = scriptResources(buildscript)
+
 allprojects {
   plugins.withType(JavaPlugin) {
     configurations {
@@ -47,17 +49,19 @@ allprojects {
       description "Generates Javadoc API documentation for the main source code. This directly invokes javadoc tool."
       group "documentation"
 
+      taskResources = resources
       dependsOn sourceSets.main.compileClasspath
-      classpath = sourceSets.main.compileClasspath;
+      classpath = sourceSets.main.compileClasspath
       srcDirSet = sourceSets.main.java;
 
-      outputDir = project.javadoc.destinationDir;
+      outputDir = project.javadoc.destinationDir
     }
 
     task renderSiteJavadoc(type: RenderJavadocTask) {
       description "Generates Javadoc API documentation for the site (relative links)."
       group "documentation"
 
+      taskResources = resources
       dependsOn sourceSets.main.compileClasspath
       classpath = sourceSets.main.compileClasspath;
       srcDirSet = sourceSets.main.java;
@@ -73,9 +77,9 @@ allprojects {
 
 // Set up titles and link up some offline docs for all documentation
 // (they may be unused but this doesn't do any harm).
-def taskResources = "${rootProject.projectDir}/gradle/documentation/render-javadoc"
-def javaJavadocPackages = rootProject.file("${taskResources}/java11/")
-def junitJavadocPackages = rootProject.file("${taskResources}/junit/")
+
+def javaJavadocPackages = rootProject.file("${resources}/java11/")
+def junitJavadocPackages = rootProject.file("${resources}/junit/")
 allprojects {
   project.tasks.withType(RenderJavadocTask) {
     title = "${project.path.startsWith(':lucene') ? 'Lucene' : 'Solr'} ${project.version} ${project.name} API"
@@ -409,7 +413,10 @@ class RenderJavadocTask extends DefaultTask {
   @Optional
   @Input
   def executable
-  
+
+  @Input
+  def taskResources
+
   /** Utility method to recursively collect all tasks with same name like this one that we depend on */
   private Set findRenderTasksInDependencies() {
     Set found = []
@@ -569,8 +576,6 @@ class RenderJavadocTask extends DefaultTask {
       throw new GradleException("Javadoc generation failed for ${project.path},\n  Options file at: ${optionsFile}\n  Command output at: ${outputFile}", cause)
     }
 
-    def taskResources = "${project.rootDir}/gradle/documentation/render-javadoc"
-
     // append some special table css, prettify css
     ant.concat(destfile: "${outputDir}/stylesheet.css", append: "true", fixlastline: "true", encoding: "UTF-8") {
       filelist(dir: taskResources, files: "table_padding.css")
diff --git a/gradle/testing/defaults-tests.gradle b/gradle/testing/defaults-tests.gradle
index 57b0c14..a277d32 100644
--- a/gradle/testing/defaults-tests.gradle
+++ b/gradle/testing/defaults-tests.gradle
@@ -20,6 +20,7 @@ import org.apache.tools.ant.types.Commandline
 import org.gradle.api.tasks.testing.logging.*
 import org.apache.lucene.gradle.ErrorReportingTestListener
 
+def resources = scriptResources(buildscript)
 def verboseModeHookInstalled = false
 
 allprojects {
@@ -108,7 +109,7 @@ allprojects {
 
       ignoreFailures = resolvedTestOption("tests.haltonfailure").toBoolean() == false
 
-      systemProperty 'java.util.logging.config.file', rootProject.file("gradle/testing/defaults-tests/logging.properties")
+      systemProperty 'java.util.logging.config.file', file("${resources}/logging.properties")
       systemProperty 'java.awt.headless', 'true'
       systemProperty 'jdk.map.althashing.threshold', '0'
 
diff --git a/gradle/testing/randomization.gradle b/gradle/testing/randomization.gradle
index 570ff6a..298bfe1 100644
--- a/gradle/testing/randomization.gradle
+++ b/gradle/testing/randomization.gradle
@@ -33,6 +33,8 @@ buildscript {
   }
 }
 
+def resources = scriptResources(buildscript)
+
 // Pick the "root" seed from which everything else is derived.
 configure(rootProject) {
   ext {
@@ -182,14 +184,14 @@ allprojects {
         if (Boolean.parseBoolean(testOptionsResolved["tests.useSecurityManager"])) {
           if (project.path == ":lucene:replicator") {
             systemProperty 'java.security.manager', "org.apache.lucene.util.TestSecurityManager"
-            systemProperty 'java.security.policy', rootProject.file("gradle/testing/policies/replicator-tests.policy")
+            systemProperty 'java.security.policy', file("${resources}/policies/replicator-tests.policy")
           } else if (project.path.startsWith(":lucene")) {
             systemProperty 'java.security.manager', "org.apache.lucene.util.TestSecurityManager"
-            systemProperty 'java.security.policy', rootProject.file("gradle/testing/policies/tests.policy")
+            systemProperty 'java.security.policy', file("${resources}/policies/tests.policy")
           } else {
             systemProperty 'common-solr.dir', commonSolrDir
             systemProperty 'java.security.manager', "org.apache.lucene.util.TestSecurityManager"
-            systemProperty 'java.security.policy', rootProject.file("gradle/testing/policies/solr-tests.policy")
+            systemProperty 'java.security.policy', file("${resources}/policies/solr-tests.policy")
           }
 
           systemProperty 'common.dir', commonDir
diff --git a/gradle/testing/policies/replicator-tests.policy b/gradle/testing/randomization/policies/replicator-tests.policy
similarity index 100%
rename from gradle/testing/policies/replicator-tests.policy
rename to gradle/testing/randomization/policies/replicator-tests.policy
diff --git a/gradle/testing/policies/solr-tests.policy b/gradle/testing/randomization/policies/solr-tests.policy
similarity index 100%
rename from gradle/testing/policies/solr-tests.policy
rename to gradle/testing/randomization/policies/solr-tests.policy
diff --git a/gradle/testing/policies/tests.policy b/gradle/testing/randomization/policies/tests.policy
similarity index 100%
rename from gradle/testing/policies/tests.policy
rename to gradle/testing/randomization/policies/tests.policy
diff --git a/gradle/validation/ecj-lint.gradle b/gradle/validation/ecj-lint.gradle
index 56bbd8d..3dcb2c0 100644
--- a/gradle/validation/ecj-lint.gradle
+++ b/gradle/validation/ecj-lint.gradle
@@ -27,6 +27,8 @@ configure(rootProject) {
   }
 }
 
+def resources = scriptResources(buildscript)
+
 allprojects {
   plugins.withType(JavaPlugin) {
     // Create a [sourceSetName]EcjLint task for each source set
@@ -69,7 +71,7 @@ allprojects {
         args += [ "-proc:none" ]
         args += [ "-nowarn" ]
         args += [ "-enableJavadoc" ]
-        args += [ "-properties", rootProject.file("gradle/validation/ecj-lint/ecj.javadocs.prefs").absolutePath ]
+        args += [ "-properties", file("${resources}/ecj.javadocs.prefs").absolutePath ]
 
         doFirst {
           tmpDst.mkdirs()
diff --git a/gradle/validation/forbidden-apis.gradle b/gradle/validation/forbidden-apis.gradle
index 8fe5199..f935386 100644
--- a/gradle/validation/forbidden-apis.gradle
+++ b/gradle/validation/forbidden-apis.gradle
@@ -18,6 +18,8 @@
 // This configures application of forbidden API rules
 // via https://github.com/policeman-tools/forbidden-apis
 
+def resources = scriptResources(buildscript)
+
 // Only apply forbidden-apis to java projects.
 allprojects { prj ->
   plugins.withId("java", {
@@ -38,7 +40,7 @@ allprojects { prj ->
       deps += ["defaults.all.txt", "defaults.${suffix}.txt"]
 
       deps.each { sig ->
-        def signaturesFile = rootProject.file("gradle/validation/forbidden-apis/${sig}")
+        def signaturesFile = file("${resources}/${sig}")
         if (signaturesFile.exists()) {
           logger.info("Signature file applied: ${sig}")
           signaturesFiles += files(signaturesFile)
@@ -73,7 +75,7 @@ allprojects { prj ->
       ]
 
       signaturesFiles = files(
-          rootProject.file("gradle/validation/forbidden-apis/defaults.tests.txt")
+          file("${resources}/defaults.tests.txt")
       )
 
       suppressAnnotations += [
@@ -127,7 +129,7 @@ allprojects { prj ->
     // This is the simplest workaround possible: just point at all the rule files and indicate
     // them as inputs. This way if a rule is modified, checks will be reapplied.
     configure([forbiddenApisMain, forbiddenApisTest]) { task ->
-      task.inputs.dir(rootProject.file("gradle/validation/forbidden-apis"))
+      task.inputs.dir(file(resources))
     }
   })
 }
\ No newline at end of file
diff --git a/gradle/validation/owasp-dependency-check.gradle b/gradle/validation/owasp-dependency-check.gradle
index 4d300b8..d58fd8b 100644
--- a/gradle/validation/owasp-dependency-check.gradle
+++ b/gradle/validation/owasp-dependency-check.gradle
@@ -20,13 +20,15 @@
 
 // If -Pvalidation.owasp=true is set the validation will also run as part of the check task.
 
+def resources = scriptResources(buildscript)
+
 configure(rootProject) {
   dependencyCheck {
     failBuildOnCVSS = propertyOrDefault("validation.owasp.threshold", 7) as Integer
     formats = ['HTML', 'JSON']
     skipProjects = [':solr:solr-ref-guide']
     skipConfigurations = ['unifiedClasspath']
-    suppressionFile = rootProject.file('gradle/validation/owasp-dependency-check/exclusions.xml')
+    suppressionFile = file("${resources}/exclusions.xml")
   }
 
   task owasp() {


[lucene-solr] 36/39: SOLR-14847: Create Solr Server TGZ (#1844)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit d2f7780b573f8e0af9d814f621f4e55d9dfa743b
Author: Mike Drob <md...@apache.org>
AuthorDate: Thu Sep 10 10:55:48 2020 -0500

    SOLR-14847: Create Solr Server TGZ (#1844)
    
    Create new targets for building solr binary release artifacts:
    
    gradlew -p solr/packaging distTar distZip
    
    Co-authored-by: Houston Putman <ho...@apache.org>
    Co-authored-by: Dawid Weiss <da...@carrotsearch.com>
    Co-authored-by: Mike Drob <md...@apache.org>
---
 help/workflow.txt           |   3 +-
 solr/packaging/build.gradle | 105 ++++++++++++++++++++++++++------------------
 2 files changed, 64 insertions(+), 44 deletions(-)

diff --git a/help/workflow.txt b/help/workflow.txt
index 7532d7e..d70b243 100644
--- a/help/workflow.txt
+++ b/help/workflow.txt
@@ -29,7 +29,8 @@ ls -R build/maven-local/
 
 Put together Solr distribution:
 gradlew -p solr/packaging assemble
-ls solr/packaging/build/solr-*
+ls solr/packaging/build/distributions/solr-* # release archives
+ls solr/packaging/build/solr-*               # expanded directory
 
 
 Other validation and checks
diff --git a/solr/packaging/build.gradle b/solr/packaging/build.gradle
index 5843d00..98503c6 100644
--- a/solr/packaging/build.gradle
+++ b/solr/packaging/build.gradle
@@ -20,6 +20,7 @@
 
 plugins {
   id 'base'
+  id 'distribution'
 }
 
 description = 'Solr packaging'
@@ -66,58 +67,76 @@ dependencies {
   server project(path: ":solr:server", configuration: "packaging")
 }
 
-task toDir(type: Sync) {
-  from(project(":solr").projectDir, {
-    include "bin/**"
-    include "licenses/**"
-    exclude "licenses/README.committers.txt"
-    include "CHANGES.txt"
-    include "LICENSE.txt"
-    include "NOTICE.txt"
-    include "README.md"
-  })
-
-  from(project(":lucene").projectDir, {
-    include "CHANGES.txt"
-    rename { file -> 'LUCENE_CHANGES.txt' }
-  })
-
-  from(configurations.contrib, {
-    into "contrib"
-  })
-
-  from(configurations.distSolr, {
-    into "dist"
-  })
-
-  from(configurations.distSolrj - configurations.distSolr, {
-    into "dist/solrj-lib"
-  })
-
-  from(configurations.example, {
-    into "example"
-  })
-
-  from(configurations.server, {
-    into "server"
-  })
+distributions {
+  main {
+    distributionBaseName = 'solr'
+    contents {
+      // Manually correct posix permissions (matters when packaging on Windows).
+      filesMatching([
+          "**/*.sh",
+          "**/bin/post",
+          "**/bin/postlogs",
+          "**/bin/solr",
+          "**/bin/init.d/solr",
+          "**/bin/solr-exporter",
+      ]) {
+        setMode 0755
+      }
+
+      from(project(":solr").projectDir, {
+        include "bin/**"
+        include "licenses/**"
+        exclude "licenses/README.committers.txt"
+        include "CHANGES.txt"
+        include "LICENSE.txt"
+        include "NOTICE.txt"
+        include "README.md"
+      })
+
+      from(project(":lucene").projectDir, {
+        include "CHANGES.txt"
+        rename { file -> 'LUCENE_CHANGES.txt' }
+      })
+
+      from(configurations.contrib, {
+        into "contrib"
+      })
+
+      from(configurations.distSolr, {
+        into "dist"
+      })
+
+      from(configurations.distSolrj - configurations.distSolr, {
+        into "dist/solrj-lib"
+      })
+
+      from(configurations.example, {
+        into "example"
+      })
+
+      from(configurations.server, {
+        into "server"
+      })
+
+      // docs/   - TODO: this is assembled via XSLT... leaving out for now.
+    }
+  }
+}
 
-  // docs/   - TODO: this is assembled via XSLT... leaving out for now.
+distTar {
+  compression = Compression.GZIP
+}
 
+installDist {
   into distDir
-
-  doLast {
-    logger.lifecycle "Solr distribution assembled under: ${distDir}"
-  }
 }
 
 task dev(type: Copy) {
   description "Assemble Solr distribution into 'development' folder at ${devDir}"
   group "build"
 
-  from toDir.outputs
+  from installDist.outputs
   into devDir
 }
 
-assemble.dependsOn toDir
-
+assemble.dependsOn installDist


[lucene-solr] 39/39: LUCENE-9474: Remove bad warning (we sometimes have non-existing directories in classpaths during compile). This warnings is not source-code related so shouldn't be enforced (Java 14)

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 2806475ea99963ceeaff2de05c6648e72a09e1ae
Author: Uwe Schindler <us...@apache.org>
AuthorDate: Sun Aug 23 21:31:44 2020 +0200

    LUCENE-9474: Remove bad warning (we sometimes have non-existing directories in classpaths during compile). This warnings is not source-code related so shouldn't be enforced (Java 14)
---
 gradle/defaults-java.gradle | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gradle/defaults-java.gradle b/gradle/defaults-java.gradle
index 3f3d036..9e1b67c 100644
--- a/gradle/defaults-java.gradle
+++ b/gradle/defaults-java.gradle
@@ -42,7 +42,6 @@ allprojects {
         "-Xlint:finally",
         "-Xlint:options",
         "-Xlint:overrides",
-        "-Xlint:path",
         "-Xlint:processing",
         "-Xlint:rawtypes",
         "-Xlint:static",


[lucene-solr] 28/39: Remove the explicit dependency to "check", as fobiddenapis installs it automatically (especially for all source sets; if we want this explicit dependency, it should depend on 'forbiddenApis' not each task). In addition precommit, also adds it.

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thelabdude pushed a commit to branch reference_impl_gradle_updates
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 97188fb968eea72532c2440d5fd27a092d148e66
Author: Uwe Schindler <us...@apache.org>
AuthorDate: Thu Sep 3 17:50:57 2020 +0200

    Remove the explicit dependency to "check", as fobiddenapis installs it automatically (especially for all source sets; if we want this explicit dependency, it should depend on 'forbiddenApis' not each task). In addition precommit, also adds it.
---
 gradle/validation/forbidden-apis.gradle | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/gradle/validation/forbidden-apis.gradle b/gradle/validation/forbidden-apis.gradle
index f935386..9c6dec0 100644
--- a/gradle/validation/forbidden-apis.gradle
+++ b/gradle/validation/forbidden-apis.gradle
@@ -83,9 +83,6 @@ allprojects { prj ->
       ]
     }
 
-    // Attach validation to check task.
-    check.dependsOn forbiddenApisMain, forbiddenApisTest
-
     // Disable sysout signatures for these projects.
     if (prj.path in [
         ":lucene:demo",