You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ma...@apache.org on 2019/06/07 08:04:41 UTC

[lucene-solr] branch jira/SOLR-13452_gradle_3 updated (c4ccba8 -> 746d5af)

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

markrmiller pushed a change to branch jira/SOLR-13452_gradle_3
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git.


    from c4ccba8  SOLR-13452: Improve unused dep checker to not count on creating the dist tgz and zip first and check if jars are used by other dep jars even if not by the module itself.
     new a94e430  SOLR-13452: Improve unused dep checker: break it up into jdep and unused tasks, output improvements, etc.
     new 7466b11  SOLR-13452: Set tools src to UTF-8.
     new 23563b5  SOLR-13452: A few small improvements and update versions.lock.
     new b750f5e  SOLR-13452: Add solr-core javacc queryparser task.
     new 746d5af  SOLR-13452: A bit more for tests, random improvements, fewer Files.

The 5 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.


Summary of changes:
 build.gradle                                       |  39 ++---
 buildSrc/build.gradle                              |  28 ++--
 buildSrc/ide/eclipse.gradle                        |   5 +-
 .../{TestRatSources.java => TestEnforcers.java}    |  15 +-
 .../lucene/gradle/CheckSourcePatterns.groovy       |   8 +-
 .../org/apache/lucene/gradle/JdepsReport.groovy    | 165 +++++++++++++++++++
 .../org/apache/lucene/gradle/SolrQPJavaCC.groovy   | 102 ++++++++++++
 .../org/apache/lucene/gradle/UnusedDeps.groovy     | 180 +++++++++------------
 buildSrc/test-build-wdocker/test-build.sh          |  12 ++
 .../{test-rat-sources.sh => test-check-sources.sh} |  25 +--
 buildSrc/test-build-wdocker/test-rat-sources.sh    |   5 +-
 lucene/analysis/common/build.gradle                |  34 ++--
 lucene/analysis/icu/build.gradle                   |   6 +-
 lucene/analysis/kuromoji/build.gradle              |  15 +-
 lucene/analysis/nori/build.gradle                  |  17 +-
 lucene/analysis/opennlp/build.gradle               |  42 ++---
 lucene/analysis/smartcn/build.gradle               |   6 +-
 lucene/analysis/stempel/build.gradle               |   6 +-
 lucene/benchmark/build.gradle                      |  24 +--
 lucene/build.gradle                                |  21 +--
 lucene/core/build.gradle                           |  10 +-
 lucene/queries/build.gradle                        |  10 +-
 lucene/test-framework/build.gradle                 |  11 +-
 settings.gradle                                    |   4 +-
 solr/build.gradle                                  |  17 +-
 solr/contrib/clustering/build.gradle               |   2 -
 solr/contrib/dataimporthandler/build.gradle        |  12 +-
 solr/core/build.gradle                             |   7 +-
 versions.lock                                      |   1 -
 29 files changed, 552 insertions(+), 277 deletions(-)
 rename buildSrc/src/buildTest/java/{TestRatSources.java => TestEnforcers.java} (73%)
 create mode 100644 buildSrc/src/main/groovy/org/apache/lucene/gradle/JdepsReport.groovy
 create mode 100644 buildSrc/src/main/groovy/org/apache/lucene/gradle/SolrQPJavaCC.groovy
 copy buildSrc/test-build-wdocker/{test-rat-sources.sh => test-check-sources.sh} (74%)


[lucene-solr] 03/05: SOLR-13452: A few small improvements and update versions.lock.

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

markrmiller pushed a commit to branch jira/SOLR-13452_gradle_3
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 23563b5732a9d2a96ced286ca392df8b13021955
Author: markrmiller <ma...@apache.org>
AuthorDate: Thu Jun 6 14:33:45 2019 -0500

    SOLR-13452: A few small improvements and update versions.lock.
---
 build.gradle                                                 | 12 +++---------
 .../main/groovy/org/apache/lucene/gradle/UnusedDeps.groovy   |  3 +++
 versions.lock                                                |  1 -
 3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/build.gradle b/build.gradle
index 147d3fe..d7a835a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -98,10 +98,10 @@ configure(luceneSolrSubProjects) {
     targetCompatibility = "11"
     
     // Use UTF-8, don't rely on local platform encoding.
-    compileJava.options.encoding = "UTF-8"
-    compileTestJava.options.encoding = "UTF-8"
+    project.compileJava.options.encoding = "UTF-8"
+    project.compileTestJava.options.encoding = "UTF-8"
     
-    sourceSets {
+    project.sourceSets {
       main.java.srcDirs = ['src/java']
       main.resources.srcDirs = ['src/resources']
       test.java.srcDirs = ['src/test']
@@ -110,12 +110,6 @@ configure(luceneSolrSubProjects) {
     
     // configure tests
     project.apply from: new File(rootProjectDir, "buildSrc/common/configure-test.gradle")
-    
-    // Custom javac options
-    tasks.withType(JavaCompile) {
-      // Don't output ALL errors in a file, stop after a few
-      options.compilerArgs << "-Xmaxerrs" << "5"
-    }
 
     task sourceJar(type: Jar) {
       classifier 'sources'
diff --git a/buildSrc/src/main/groovy/org/apache/lucene/gradle/UnusedDeps.groovy b/buildSrc/src/main/groovy/org/apache/lucene/gradle/UnusedDeps.groovy
index fe6fd53..8bc75b3 100644
--- a/buildSrc/src/main/groovy/org/apache/lucene/gradle/UnusedDeps.groovy
+++ b/buildSrc/src/main/groovy/org/apache/lucene/gradle/UnusedDeps.groovy
@@ -51,6 +51,9 @@ class UnusedDeps extends DefaultTask {
   @Inject
   public UnusedDeps(File inputDirectory) {
     
+    group = 'Help'
+    description = "Lists dependencies that may be unused for a module."
+    
     if (!project.configurations.hasProperty('runtimeClasspath')) {
       return
     }
diff --git a/versions.lock b/versions.lock
index 424d337..a6f1949 100644
--- a/versions.lock
+++ b/versions.lock
@@ -222,4 +222,3 @@ org.tallison:jmatio:1.5 (2 constraints: a810a0b8)
 org.tukaani:xz:1.8 (2 constraints: ae100fb9)
 ua.net.nlp:morfologik-ukrainian-search:3.9.0 (1 constraints: 0e051536)
 xerces:xercesImpl:2.9.1 (1 constraints: 0e051136)
-xpp3:xpp3:1.1.3.3 (1 constraints: 0e0ef84b)


[lucene-solr] 04/05: SOLR-13452: Add solr-core javacc queryparser task.

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

markrmiller pushed a commit to branch jira/SOLR-13452_gradle_3
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit b750f5e6756060c68d52f4ee06e648dd8b0eb5f7
Author: markrmiller <ma...@apache.org>
AuthorDate: Thu Jun 6 16:16:03 2019 -0500

    SOLR-13452: Add solr-core javacc queryparser task.
---
 buildSrc/build.gradle                              |  2 +
 .../groovy/org/apache/lucene/gradle/JavaCC.groovy  | 94 ++++++++++++++++++++++
 solr/build.gradle                                  |  5 ++
 solr/core/build.gradle                             |  5 ++
 4 files changed, 106 insertions(+)

diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index 3d81a98..9911832 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -40,6 +40,7 @@ configurations {
   jflex
   rat
   junit4
+  javacc
   
   jflex.extendsFrom implementation
 }
@@ -48,6 +49,7 @@ dependencies {
   jflex "de.jflex:jflex:1.7.0"
   rat "org.apache.rat:apache-rat:0.11"
   junit4 "com.carrotsearch.randomizedtesting:junit4-ant"
+  javacc "net.java.dev.javacc:javacc:5.0"
 }
 
 sourceSets {
diff --git a/buildSrc/src/main/groovy/org/apache/lucene/gradle/JavaCC.groovy b/buildSrc/src/main/groovy/org/apache/lucene/gradle/JavaCC.groovy
new file mode 100644
index 0000000..08106fa
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/lucene/gradle/JavaCC.groovy
@@ -0,0 +1,94 @@
+package org.apache.lucene.gradle
+/*
+ * 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.api.DefaultTask
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.Optional
+import org.gradle.api.tasks.InputDirectory
+import org.gradle.api.tasks.InputFile
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.tasks.TaskAction
+
+class JavaCC extends DefaultTask {
+  
+  @InputFile
+  File inputFile
+  
+  @OutputDirectory
+  File target
+  
+  @TaskAction
+  void javacc() {
+    
+    String javaCCHome
+    String javaCCJarName
+    
+    project.project(":buildSrc").configurations.javacc.files.each {
+      if (it.getName().startsWith("javacc") && it.getName().endsWith(".jar")) {
+        javaCCHome = it.getParentFile().getAbsolutePath()
+        javaCCJarName = it.getName()
+      }
+    }
+    
+    project.sync {
+      from (javaCCHome + "/" + javaCCJarName)
+      into (javaCCHome)
+      rename { String fileName ->
+        fileName = "javacc.jar"
+      }
+    }
+    
+    ant.taskdef(classname: 'org.apache.tools.ant.taskdefs.optional.javacc.JavaCC',
+    name: 'javacc',
+    classpath: project.project(":buildSrc").configurations.javacc.asPath)
+
+    project.mkdir("src/java/org/apache/solr/parser")
+    
+    ant.delete() {
+      ant.fileset(dir: "${target}", includes: "*.java") {
+        ant.containsregexp(expression: "Generated.*By.*JavaCC")
+      }
+    }
+    
+    ant.javacc(target: inputFile.getAbsolutePath(), outputDirectory: target.getAbsolutePath(), javacchome: javaCCHome)
+    
+    
+    // Change the incorrect public ctors for QueryParser to be protected instead
+    ant.replaceregexp(file:"src/java/org/apache/solr/parser/QueryParser.java",
+    byline:  "true",
+    match:   "public QueryParser\\(CharStream ",
+    replace: "protected QueryParser(CharStream ")
+    ant.replaceregexp(file:"src/java/org/apache/solr/parser/QueryParser.java",
+    byline: "true",
+    match:  "public QueryParser\\(QueryParserTokenManager ",
+    replace:"protected QueryParser(QueryParserTokenManager ")
+    // change an exception used for signaling to be static
+    ant.replaceregexp(file: "src/java/org/apache/solr/parser/QueryParser.java",
+    byline: "true",
+    match: "final private LookaheadSuccess jj_ls =",
+    replace: "static final private LookaheadSuccess jj_ls =")
+    ant.replace(token: "StringBuffer", value: "StringBuilder", encoding: "UTF-8") {
+      ant.fileset(dir: "src/java/org/apache/solr/parser", includes: "ParseException.java TokenMgrError.java")
+    }
+    
+    ant.fixcrlf(srcdir: "${target}", includes: "*.java", encoding: "UTF-8") {
+      ant.containsregexp(expression: "Generated.*By.*JavaCC")
+    }
+  }
+}
+
+
diff --git a/solr/build.gradle b/solr/build.gradle
index 9ea77bc..d05b0e4 100644
--- a/solr/build.gradle
+++ b/solr/build.gradle
@@ -36,7 +36,12 @@ task packageDist(type: org.apache.lucene.gradle.PackageLuceneSolrDist) {
 
 subprojects {
   File target = File.createTempDir()
+  target.deleteOnExit()
   tasks.create("jdepsReport", org.apache.lucene.gradle.JdepsReport, target)
   tasks.create("unusedDeps", org.apache.lucene.gradle.UnusedDeps, target)
   unusedDeps.dependsOn jdepsReport
+  
+  unusedDeps.doLast {
+    deleteDirectory(target)
+  }
 }
diff --git a/solr/core/build.gradle b/solr/core/build.gradle
index ffd12ca..824c869 100644
--- a/solr/core/build.gradle
+++ b/solr/core/build.gradle
@@ -208,3 +208,8 @@ forbiddenApisTest {
   exclude 'org/apache/solr/internal/**'
   exclude 'org/apache/hadoop/**'
 }
+
+task javacc(type: org.apache.lucene.gradle.JavaCC) {
+  inputFile file("${projectDir}/src/java/org/apache/solr/parser/QueryParser.jj")
+  target file("${projectDir}/src/java/org/apache/lucene/analysis/standard")
+}


[lucene-solr] 05/05: SOLR-13452: A bit more for tests, random improvements, fewer Files.

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

markrmiller pushed a commit to branch jira/SOLR-13452_gradle_3
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 746d5af628317bffb3adf64e6c0d1819950469c6
Author: markrmiller <ma...@apache.org>
AuthorDate: Fri Jun 7 03:04:19 2019 -0500

    SOLR-13452: A bit more for tests, random improvements, fewer Files.
---
 build.gradle                                       | 27 ++++++----
 buildSrc/build.gradle                              | 28 +++++-----
 buildSrc/ide/eclipse.gradle                        |  5 +-
 .../{TestRatSources.java => TestEnforcers.java}    | 15 +++++-
 .../lucene/gradle/CheckSourcePatterns.groovy       |  8 +--
 .../org/apache/lucene/gradle/JdepsReport.groovy    |  1 -
 .../gradle/{JavaCC.groovy => SolrQPJavaCC.groovy}  | 62 ++++++++++++----------
 buildSrc/test-build-wdocker/test-build.sh          | 12 +++++
 .../{test-rat-sources.sh => test-check-sources.sh} | 25 +++------
 buildSrc/test-build-wdocker/test-rat-sources.sh    |  5 +-
 lucene/analysis/common/build.gradle                | 34 ++++++------
 lucene/analysis/icu/build.gradle                   |  4 +-
 lucene/analysis/kuromoji/build.gradle              | 10 ++--
 lucene/analysis/nori/build.gradle                  | 12 ++---
 lucene/analysis/opennlp/build.gradle               | 42 +++++++--------
 lucene/analysis/smartcn/build.gradle               |  6 +--
 lucene/analysis/stempel/build.gradle               |  6 +--
 lucene/benchmark/build.gradle                      | 24 ++++-----
 lucene/build.gradle                                | 19 ++++---
 lucene/core/build.gradle                           | 10 ++--
 lucene/queries/build.gradle                        | 10 ++--
 lucene/test-framework/build.gradle                 |  8 +--
 settings.gradle                                    |  4 +-
 solr/build.gradle                                  |  9 ++--
 solr/core/build.gradle                             |  6 +--
 25 files changed, 209 insertions(+), 183 deletions(-)

diff --git a/build.gradle b/build.gradle
index d7a835a..3633255 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,12 +17,13 @@
 
 import org.apache.lucene.gradle.CheckWorkingCopy
 import org.apache.lucene.gradle.LuceneSolrForbiddenApisPlugin
+import org.apache.commons.io.FilenameUtils
 
 plugins {
   id "com.palantir.consistent-versions" version "1.8.0"
 }
 
-buildDir = new File("build")
+buildDir = file("build")
 
 // define lucene-solr project lists that exclude buildSrc
 def luceneSolrProjects = allprojects.findAll { project -> project.name != 'buildSrc'};
@@ -30,8 +31,17 @@ def luceneSolrSubProjects = subprojects.findAll { project -> project.name != 'bu
 
 def rootProjectDir = project.rootProject.projectDir;
 
-// make sure ant task logging shows up by default
-ant.lifecycleLogLevel = "INFO"
+allprojects {
+  // make sure ant task logging shows up by default
+  ant.lifecycleLogLevel = "INFO"
+  
+  // sugare file path handler - to deal with path.separator on string paths
+  ext.filePath = { path -> file(path).getAbsolutePath() }
+  
+  // sugar multi part File
+  ext.mfile = { file1, file2 -> new File(file(file1), file2.toString()) }
+  
+}
 
 // TOC
 // -> lucene-solr all project config
@@ -45,9 +55,9 @@ ant.lifecycleLogLevel = "INFO"
 configure(luceneSolrProjects) {
 
   // setup repositories
-  apply from: new File(rootProjectDir, "buildSrc/common/configure-repositories.gradle")
+  apply from: mfile(rootProjectDir, 'buildSrc/common/configure-repositories.gradle')
   
-  buildDir = new File("build")
+  buildDir = file("build")
   
   apply plugin: 'idea'
   apply plugin: 'eclipse'
@@ -109,7 +119,7 @@ configure(luceneSolrSubProjects) {
     }
     
     // configure tests
-    project.apply from: new File(rootProjectDir, "buildSrc/common/configure-test.gradle")
+    project.apply from: mfile(rootProjectDir, 'buildSrc/common/configure-test.gradle')
 
     task sourceJar(type: Jar) {
       classifier 'sources'
@@ -157,8 +167,8 @@ configure(allprojects) {
   apply plugin: 'idea'
   
   plugins.withType(JavaPlugin) {
-    project.apply from: new File(rootProjectDir, "buildSrc/ide/eclipse.gradle")
-    project.apply from: new File(rootProjectDir, "buildSrc/ide/idea.gradle")
+    project.apply from: mfile(rootProjectDir, 'buildSrc/ide/eclipse.gradle')
+    project.apply from: mfile(rootProjectDir, 'buildSrc/ide/idea.gradle')
   }
   
   // dependencies block that applies to all projects
@@ -194,4 +204,3 @@ def javaDocProjects = subprojects.findAll { project -> !noJavaDocModules.contain
 //     destinationDir = file("${buildDir}/docs")
 //   }
 // }
-
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index 9911832..48dae1a 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -3,13 +3,13 @@
  * 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 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,
+ * 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.
@@ -19,11 +19,11 @@ apply plugin: 'groovy'
 apply plugin: 'java'
 apply plugin: 'java-gradle-plugin'
 
-buildDir = new File("build")
+buildDir = file('build')
 
 group = 'org.apache.lucene.gradle'
 
-apply from: new File("common/configure-repositories.gradle")
+apply from: file('common/configure-repositories.gradle')
 
 dependencies {
   implementation gradleApi()
@@ -32,8 +32,8 @@ dependencies {
   implementation 'org.eclipse.jgit:org.eclipse.jgit:4.6.0.201612231935-r'
   implementation 'de.thetaphi:forbiddenapis:2.6'
   implementation 'com.ibm.icu:icu4j:62.1'
-  implementation "org.apache.rat:apache-rat:0.11"
-  implementation "junit:junit:4.12"
+  implementation 'org.apache.rat:apache-rat:0.11'
+  implementation 'junit:junit:4.12'
 }
 
 configurations {
@@ -46,10 +46,10 @@ configurations {
 }
 
 dependencies {
-  jflex "de.jflex:jflex:1.7.0"
-  rat "org.apache.rat:apache-rat:0.11"
-  junit4 "com.carrotsearch.randomizedtesting:junit4-ant"
-  javacc "net.java.dev.javacc:javacc:5.0"
+  jflex 'de.jflex:jflex:1.7.0'
+  rat 'org.apache.rat:apache-rat:0.11'
+  junit4 'com.carrotsearch.randomizedtesting:junit4-ant'
+  javacc 'net.java.dev.javacc:javacc:5.0'
 }
 
 sourceSets {
@@ -64,12 +64,12 @@ sourceSets {
   }
   all {
     java {
-      sourceCompatibility = "11"
-      targetCompatibility = "11"
+      sourceCompatibility = '11'
+      targetCompatibility = '11'
       
       // Use UTF-8, don't rely on local platform encoding.
-      compileJava.options.encoding = "UTF-8"
-      compileTestJava.options.encoding = "UTF-8"
+      compileJava.options.encoding = 'UTF-8'
+      compileTestJava.options.encoding = 'UTF-8'
     }
   }
 }
diff --git a/buildSrc/ide/eclipse.gradle b/buildSrc/ide/eclipse.gradle
index 56f8f8b..652db42 100644
--- a/buildSrc/ide/eclipse.gradle
+++ b/buildSrc/ide/eclipse.gradle
@@ -78,9 +78,8 @@ eclipse {
       }
       
       // Jetty mod files make eclipse sad
-      def settingsDir = new File("${projectDir}/.settings")
-      mkdir(settingsDir)
-      new File(settingsDir, "org.eclipse.wst.validation.prefs").text = """
+      mkdir('.settings')
+      file('.settings/org.eclipse.wst.validation.prefs').text = """
 eclipse.preferences.version=1
 override=true
 suspend=true
diff --git a/buildSrc/src/buildTest/java/TestRatSources.java b/buildSrc/src/buildTest/java/TestEnforcers.java
similarity index 73%
rename from buildSrc/src/buildTest/java/TestRatSources.java
rename to buildSrc/src/buildTest/java/TestEnforcers.java
index 993a3dc..027314d 100644
--- a/buildSrc/src/buildTest/java/TestRatSources.java
+++ b/buildSrc/src/buildTest/java/TestEnforcers.java
@@ -18,9 +18,9 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-public class TestRatSources extends BaseTestClass {
+public class TestEnforcers extends BaseTestClass {
   
-  public TestRatSources() {
+  public TestEnforcers() {
 
   }
   
@@ -40,6 +40,10 @@ public class TestRatSources extends BaseTestClass {
     
     cmd = new String[]{"bash", "-c", "docker exec --user ${UID} -t ${CONTAINER_NAME} bash -c \"rm /home/lucene/project/lucene/core/src/java/org/no_license_test_file.xml\""};
     runCmd(cmd, env, false, false);
+    
+    
+    cmd = new String[]{"bash", "-c", "docker exec --user ${UID} -t ${CONTAINER_NAME} bash -c \"rm /home/lucene/project/solr/contrib/clustering/src/java/org/tab_file.xml\""};
+    runCmd(cmd, env, false, false);
   }
   
   @Test
@@ -50,4 +54,11 @@ public class TestRatSources extends BaseTestClass {
     assertEquals("Testing test-build.sh failed", 0, result.returnCode);
   }
 
+  @Test
+  public void testCheckSources() throws Exception {
+    System.out.println("Start test-check-sources.sh test in Docker container (" + env + ") ...");
+    String[] cmd = new String[]{"bash", "test-build-wdocker/test-check-sources.sh"};
+    PbResult result = runCmd(cmd, env, false, false, false);
+    assertEquals("Testing test-build.sh failed", 0, result.returnCode);
+  }
 }
diff --git a/buildSrc/src/main/groovy/org/apache/lucene/gradle/CheckSourcePatterns.groovy b/buildSrc/src/main/groovy/org/apache/lucene/gradle/CheckSourcePatterns.groovy
index 749bc8e..86bdc48 100644
--- a/buildSrc/src/main/groovy/org/apache/lucene/gradle/CheckSourcePatterns.groovy
+++ b/buildSrc/src/main/groovy/org/apache/lucene/gradle/CheckSourcePatterns.groovy
@@ -158,10 +158,10 @@ class CheckSourcePatterns extends DefaultTask {
     (~$/import java\.lang\.\w+;/$) : 'java.lang import is unnecessary'
   ]
   
-   private def found = 0
-   private def violations = new TreeSet()
-   protected def reportViolation = { f, name ->
-    log.error(name + ': ' + f.toString().substring(baseDir.length() + 1).replace(File.separatorChar, (char)'/'))
+  protected def found = 0
+  protected def violations = new TreeSet()
+  protected def reportViolation = { f, name ->
+  log.error(name + ': ' + f.toString().substring(baseDir.length() + 1).replace(File.separatorChar, (char)'/'))
     violations.add(name)
     found++
   }
diff --git a/buildSrc/src/main/groovy/org/apache/lucene/gradle/JdepsReport.groovy b/buildSrc/src/main/groovy/org/apache/lucene/gradle/JdepsReport.groovy
index 5c48e2b..143212f 100644
--- a/buildSrc/src/main/groovy/org/apache/lucene/gradle/JdepsReport.groovy
+++ b/buildSrc/src/main/groovy/org/apache/lucene/gradle/JdepsReport.groovy
@@ -114,7 +114,6 @@ class JdepsReport extends DefaultTask {
     jdepsDir.mkdirs()
   }
 
-  
   @TaskAction
   void execute() {
     // make sure ant task logging shows up by default
diff --git a/buildSrc/src/main/groovy/org/apache/lucene/gradle/JavaCC.groovy b/buildSrc/src/main/groovy/org/apache/lucene/gradle/SolrQPJavaCC.groovy
similarity index 50%
rename from buildSrc/src/main/groovy/org/apache/lucene/gradle/JavaCC.groovy
rename to buildSrc/src/main/groovy/org/apache/lucene/gradle/SolrQPJavaCC.groovy
index 08106fa..bcc2549 100644
--- a/buildSrc/src/main/groovy/org/apache/lucene/gradle/JavaCC.groovy
+++ b/buildSrc/src/main/groovy/org/apache/lucene/gradle/SolrQPJavaCC.groovy
@@ -23,7 +23,7 @@ import org.gradle.api.tasks.InputFile
 import org.gradle.api.tasks.OutputDirectory
 import org.gradle.api.tasks.TaskAction
 
-class JavaCC extends DefaultTask {
+class SolrQPJavaCC extends DefaultTask {
   
   @InputFile
   File inputFile
@@ -37,30 +37,32 @@ class JavaCC extends DefaultTask {
     String javaCCHome
     String javaCCJarName
     
-    project.project(":buildSrc").configurations.javacc.files.each {
-      if (it.getName().startsWith("javacc") && it.getName().endsWith(".jar")) {
+    project.project(':buildSrc').configurations.javacc.files.each {
+      if (it.getName().startsWith('javacc') && it.getName().endsWith('.jar')) {
         javaCCHome = it.getParentFile().getAbsolutePath()
         javaCCJarName = it.getName()
       }
     }
     
-    project.sync {
-      from (javaCCHome + "/" + javaCCJarName)
-      into (javaCCHome)
-      rename { String fileName ->
-        fileName = "javacc.jar"
+    if (!project.file(javaCCHome + '/javacc.jar').exists()) {
+      project.copy {
+        from (javaCCHome + '/' + javaCCJarName)
+        into (javaCCHome)
+        rename { String fileName ->
+          fileName = 'javacc.jar'
+        }
       }
     }
     
     ant.taskdef(classname: 'org.apache.tools.ant.taskdefs.optional.javacc.JavaCC',
     name: 'javacc',
-    classpath: project.project(":buildSrc").configurations.javacc.asPath)
+    classpath: project.project(':buildSrc').configurations.javacc.asPath)
 
-    project.mkdir("src/java/org/apache/solr/parser")
+    project.mkdir('src/java/org/apache/solr/parser')
     
     ant.delete() {
-      ant.fileset(dir: "${target}", includes: "*.java") {
-        ant.containsregexp(expression: "Generated.*By.*JavaCC")
+      ant.fileset(dir: target.getAbsolutePath(), includes: '*.java') {
+        ant.containsregexp(expression: 'Generated.*By.*JavaCC')
       }
     }
     
@@ -68,25 +70,31 @@ class JavaCC extends DefaultTask {
     
     
     // Change the incorrect public ctors for QueryParser to be protected instead
-    ant.replaceregexp(file:"src/java/org/apache/solr/parser/QueryParser.java",
-    byline:  "true",
-    match:   "public QueryParser\\(CharStream ",
-    replace: "protected QueryParser(CharStream ")
-    ant.replaceregexp(file:"src/java/org/apache/solr/parser/QueryParser.java",
-    byline: "true",
-    match:  "public QueryParser\\(QueryParserTokenManager ",
-    replace:"protected QueryParser(QueryParserTokenManager ")
+    ant.replaceregexp(file: project.filePath('src/java/org/apache/solr/parser/QueryParser.java'),
+    byline:  'true',
+    match:   'public QueryParser\\(CharStream ',
+    replace: 'protected QueryParser(CharStream ')
+    
+    ant.replaceregexp(file: project.filePath('src/java/org/apache/solr/parser/QueryParser.java'),
+    byline: 'true',
+    match:  'public QueryParser\\(QueryParserTokenManager ',
+    replace:'protected QueryParser(QueryParserTokenManager ')
+    
     // change an exception used for signaling to be static
-    ant.replaceregexp(file: "src/java/org/apache/solr/parser/QueryParser.java",
-    byline: "true",
-    match: "final private LookaheadSuccess jj_ls =",
-    replace: "static final private LookaheadSuccess jj_ls =")
+    ant.replaceregexp(file: project.filePath("src/java/org/apache/solr/parser/QueryParser.java"),
+                   byline: "true",
+                   match: "final private LookaheadSuccess jj_ls =",
+                   replace: "static final private LookaheadSuccess jj_ls =")
     ant.replace(token: "StringBuffer", value: "StringBuilder", encoding: "UTF-8") {
-      ant.fileset(dir: "src/java/org/apache/solr/parser", includes: "ParseException.java TokenMgrError.java")
+       ant.fileset(dir: project.filePath("src/java/org/apache/solr/parser"), includes: "ParseException.java TokenMgrError.java")
+    }
+
+    ant.replace(token: 'StringBuffer', value: 'StringBuilder', encoding: 'UTF-8') {
+      ant.fileset(dir: project.filePath('src/java/org/apache/solr/parser'), includes: 'ParseException.java TokenMgrError.java')
     }
     
-    ant.fixcrlf(srcdir: "${target}", includes: "*.java", encoding: "UTF-8") {
-      ant.containsregexp(expression: "Generated.*By.*JavaCC")
+    ant.fixcrlf(srcdir: target.getAbsolutePath(), includes: '*.java', encoding: 'UTF-8') {
+      ant.containsregexp(expression: 'Generated.*By.*JavaCC')
     }
   }
 }
diff --git a/buildSrc/test-build-wdocker/test-build.sh b/buildSrc/test-build-wdocker/test-build.sh
index 24da83f..8e88270 100644
--- a/buildSrc/test-build-wdocker/test-build.sh
+++ b/buildSrc/test-build-wdocker/test-build.sh
@@ -67,6 +67,18 @@ exec "${cmd}" "${exec_args}" || { exit 1; }
 cmd="cd /home/lucene/project;./gradlew cleanEclipse eclipse"
 exec "${cmd}" "${exec_args}" || { exit 1; }
 
+# test unusedDeps task
+cmd="cd /home/lucene/project;./gradlew solr:solr-core:unusedDeps"
+exec "${cmd}" "${exec_args}" || { exit 1; }
+
+# try deeper structure
+cmd="cd /home/lucene/project;./gradlew solr:contrib:solr-contrib-clustering:unusedDeps"
+exec "${cmd}" "${exec_args}" || { exit 1; }
+
+# test solr qp javacc task
+# cmd="cd /home/lucene/project;./gradlew javacc"
+# exec "${cmd}" "${exec_args}" || { exit 1; }
+
 # we should still be able to build now
 cmd="cd /home/lucene/project;./gradlew build -x test"
 exec "${cmd}" "${exec_args}" || { exit 1; }
diff --git a/buildSrc/test-build-wdocker/test-rat-sources.sh b/buildSrc/test-build-wdocker/test-check-sources.sh
similarity index 74%
copy from buildSrc/test-build-wdocker/test-rat-sources.sh
copy to buildSrc/test-build-wdocker/test-check-sources.sh
index cdb65823..6fe2aaf 100644
--- a/buildSrc/test-build-wdocker/test-rat-sources.sh
+++ b/buildSrc/test-build-wdocker/test-check-sources.sh
@@ -47,30 +47,21 @@ set -x
 
 # NOTE: we don't clean right now, as it would wipe out buildSrc/build on us for the host
 
-# first check that rat passes
-cmd="cd /home/lucene/project;./gradlew ratSources"
+# first check that checkSourcePatterns passes
+cmd="cd /home/lucene/project;./gradlew checkSourcePatterns"
 exec "${cmd}" "${exec_args}" || { exit 1; }
 
 # create an xml file with no license in lucene
-cmd="ls /home/lucene/project;touch /home/lucene/project/lucene/core/src/java/org/no_license_test_file.xml"
+cmd="ls /home/lucene/project;echo \\"\t\\" >> /home/lucene/project/solr/contrib/clustering/src/java/org/tab_file.xml"
 exec "${cmd}" "${exec_args}" || { exit 1; }
 
-# test that rat fails on our test file
-cmd="cd /home/lucene/project;./gradlew ratSources"
+# test that checkSourcePatterns fails on our test file
+cmd="cd /home/lucene/project;./gradlew checkSourcePatterns"
 if [ exec "${cmd}" "${exec_args}" ]; then
-  exit 1 # rat should fail!
-else
-  exit 0	
+  echocheckSourcePatterns should fail!
+  exit 1
 fi
 
 # clean test file
-cmd="rm /home/lucene/project/lucene/core/src/java/org/no_license_test_file.xml"
+cmd="rm /home/lucene/project/solr/contrib/clustering/src/java/org/tab_file.xml"
 exec "${cmd}" "${exec_args}" || { exit 1; }
-
-# create a java file with no license in solr tests
-cmd="ls /home/lucene/project;touch /home/lucene/project/solr/core/src/test/org/no_license_test_file.java"
-if [ exec "${cmd}" "${exec_args}" ]; then
-  exit 1 # rat should fail!
-else
-  exit 0	
-fi
diff --git a/buildSrc/test-build-wdocker/test-rat-sources.sh b/buildSrc/test-build-wdocker/test-rat-sources.sh
index cdb65823..2b9e8c4 100644
--- a/buildSrc/test-build-wdocker/test-rat-sources.sh
+++ b/buildSrc/test-build-wdocker/test-rat-sources.sh
@@ -70,7 +70,6 @@ exec "${cmd}" "${exec_args}" || { exit 1; }
 # create a java file with no license in solr tests
 cmd="ls /home/lucene/project;touch /home/lucene/project/solr/core/src/test/org/no_license_test_file.java"
 if [ exec "${cmd}" "${exec_args}" ]; then
-  exit 1 # rat should fail!
-else
-  exit 0	
+  echo rat should fail!
+  exit 1 
 fi
diff --git a/lucene/analysis/common/build.gradle b/lucene/analysis/common/build.gradle
index 2f18753..74702d7 100644
--- a/lucene/analysis/common/build.gradle
+++ b/lucene/analysis/common/build.gradle
@@ -21,9 +21,9 @@ apply plugin: org.apache.lucene.gradle.PartOfDist
 
 archivesBaseName = 'lucene-analyzers-common'
 
-def unicodePropsJavaFile = "/src/java/org/apache/lucene/analysis/util/UnicodeProps.java"
+def unicodePropsJavaFile = file("src/java/org/apache/lucene/analysis/util/UnicodeProps.java")
 
-def snowballProgramsDir = "${projectDir}/src/java/org/tartarus/snowball/ext"
+def snowballProgramsDir = file("src/java/org/tartarus/snowball/ext")
 
 task jarTest (type: Jar) {
   from sourceSets.test.output
@@ -50,7 +50,7 @@ ratSources {
 }
 
 task fixCRLFUnicodeData(type: org.apache.lucene.gradle.FixCRLF) {
-  file = new File("${projectDir}" + unicodePropsJavaFile)
+  file = unicodePropsJavaFile
   encoding = "UTF-8"
 }
 
@@ -58,57 +58,57 @@ task unicodeData(type: org.apache.lucene.gradle.GenerateUnicodeData) {
   group = 'Build Regenerate'
   description = "Regenerates Unicode data src files."
   
-  unicodePropsFile = new File("${projectDir}" + unicodePropsJavaFile)
+  unicodePropsFile = unicodePropsJavaFile
   
   finalizedBy fixCRLFUnicodeData
 }
 
 task generateJflexHtmlCharEntities() {
   doLast {
-    ant.exec(dir: "src/java/org/apache/lucene/analysis/charfilter",
-             output: "src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex",
+    ant.exec(dir: filePath("src/java/org/apache/lucene/analysis/charfilter"),
+             output: filePath("src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex"),
              executable: "${python_exe}", failonerror:"true", logerror:"true") {
              ant.arg(value: "-B")
              ant.arg(value: "htmlentity.py")
     }
-    ant.fixcrlf(file: "src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex", encoding: "UTF-8")
+    ant.fixcrlf(file: filePath("src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex"), encoding: "UTF-8")
   }
 }
 
 task jflexHTMLStripCharFilter(type: org.apache.lucene.gradle.JFlex) {
-  inputDir = new File("${projectDir}/src/java/org/apache/lucene/analysis/charfilter")
+  inputDir = file("src/java/org/apache/lucene/analysis/charfilter")
   fileName = "HTMLStripCharFilter"
   disableBufferExpansion = false
-  target = new File("${projectDir}/src/java/org/apache/lucene/analysis/charfilter")
+  target = file("src/java/org/apache/lucene/analysis/charfilter")
   dependsOn generateJflexHtmlCharEntities
 }
 
 task jflexWikiTokenizer(type: org.apache.lucene.gradle.JFlex) {
-  inputDir = new File("${projectDir}/src/java/org/apache/lucene/analysis/wikipedia")
+  inputDir = file("src/java/org/apache/lucene/analysis/wikipedia")
   fileName = "WikipediaTokenizerImpl"
   disableBufferExpansion = false
-  target = new File("${projectDir}/src/java/org/apache/lucene/analysis/wikipedia")
+  target = file("src/java/org/apache/lucene/analysis/wikipedia")
   
   mustRunAfter project.rootProject.project(":lucene:lucene-core").runJflex
 }
 
 task jflexClassicAnalyzer(type: org.apache.lucene.gradle.JFlex) {
-  inputDir = new File("${projectDir}/src/java/org/apache/lucene/analysis/standard")
+  inputDir = file("src/java/org/apache/lucene/analysis/standard")
   fileName = "ClassicTokenizerImpl"
   disableBufferExpansion = false
-  target = new File("${projectDir}/src/java/org/apache/lucene/analysis/standard")
+  target = file("src/java/org/apache/lucene/analysis/standard")
 
-  mustRunAfter project.rootProject.project(":lucene:lucene-core").runJflex
+  mustRunAfter project(":lucene:lucene-core").runJflex
 }
 
 task jflexUAX29URLEmailTokenizer(type: org.apache.lucene.gradle.JFlex) {
   group = 'Build Regenerate'
   description = "Generates UAX29URLEmailTokenizer using jflex."
   
-  inputDir = new File("${projectDir}/src/java/org/apache/lucene/analysis/standard")
+  inputDir = file("/src/java/org/apache/lucene/analysis/standard")
   fileName = "UAX29URLEmailTokenizerImpl"
   disableBufferExpansion = true
-  target = new File("${projectDir}/src/java/org/apache/lucene/analysis/standard")
+  target = file("src/java/org/apache/lucene/analysis/standard")
 }
 
 task runJflex {
@@ -172,7 +172,7 @@ task patchSnowball {
     ant.replaceregexp(match: "private final static \\w+Stemmer methodObject\\b.*\$", replace: "/* patched */ private static final java.lang.invoke.MethodHandles.Lookup methodObject = java.lang.invoke.MethodHandles.lookup();", flags: "m", encoding: "UTF-8") {
       ant.fileset(refid:"snowball.programs")
     }
-    ant.fixcrlf(srcdir:"${snowballProgramsDir}", includes:"*Stemmer.java", tab:"remove", tablength:"2", encoding: "UTF-8", javafiles: "yes", fixlast: "yes")
+    ant.fixcrlf(srcdir: snowballProgramsDir, includes:"*Stemmer.java", tab:"remove", tablength:"2", encoding: "UTF-8", javafiles: "yes", fixlast: "yes")
   }
 }
 
diff --git a/lucene/analysis/icu/build.gradle b/lucene/analysis/icu/build.gradle
index 2f9fdf8..62a1b4a 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/analysis/icu/build.gradle
@@ -55,13 +55,13 @@ task genUtr30DataFiles(type: JavaExec) {
   workingDir "src/data/utr30"
 }
 
-def resourcesDir = "${projectDir}/src/resources"
+def resourcesDir = "src/resources"
 
 task gennorm2() {
   group = 'Build Regenerate'
   description = "Compiles norm2 rules. 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/ or sudo apt install icu-devtools"
   doLast {
-    new File(buildDir, "gennorm2").mkdirs()
+    mkdir("${buildDir}/gennorm2")
     exec {
       executable "gennorm2"
       args = ['-v', '-s', "${projectDir}/src/data/utr30", 'nfc.txt', 'nfkc.txt', 'nfkc_cf.txt', 'BasicFoldings.txt', 'DiacriticFolding.txt', 'DingbatFolding.txt', 'HanRadicalFolding.txt', 'NativeDigitFolding.txt', '-o', "${buildDir}/gennorm2/utr30.tmp"]
diff --git a/lucene/analysis/kuromoji/build.gradle b/lucene/analysis/kuromoji/build.gradle
index 0543e67..d681f41 100644
--- a/lucene/analysis/kuromoji/build.gradle
+++ b/lucene/analysis/kuromoji/build.gradle
@@ -59,11 +59,11 @@ def ipadicFilename = "mecab-ipadic-${ipadicVersion}"
 
 task downloadDict(type: org.apache.lucene.gradle.Download) {
   sourceUrl = "https://jaist.dl.sourceforge.net/project/mecab/mecab-ipadic/${ipadicVersion}/${ipadicFilename}.tar.gz"
-  target = new File("${buildDir}/${ipadicFilename}.tar.gz")
+  target = mfile("${buildDir}", "${ipadicFilename}.tar.gz")
   
   doLast {
-    ant.gunzip(src: "${buildDir}/${ipadicFilename}.tar.gz")
-    ant.untar(src: "${buildDir}/${ipadicFilename}.tar", dest: "${buildDir}")
+    ant.gunzip(src: filePath("${buildDir}/${ipadicFilename}.tar.gz"))
+    ant.untar(src: filePath("${buildDir}/${ipadicFilename}.tar"), dest: "${buildDir}")
   }
 }
 
@@ -92,8 +92,8 @@ task buildKuromojiDict(type: JavaExec) {
   jvmArgs '-Xmx1G'
   
   args 'ipadic'
-  args "${buildDir}/${ipadicFilename}"
-  args "${projectDir}/src/resources"
+  args filePath("${buildDir}/${ipadicFilename}")
+  args filePath('src/resources')
   args 'euc-jp'
   args 'false'
   
diff --git a/lucene/analysis/nori/build.gradle b/lucene/analysis/nori/build.gradle
index a636c8e..66230d5 100644
--- a/lucene/analysis/nori/build.gradle
+++ b/lucene/analysis/nori/build.gradle
@@ -58,17 +58,17 @@ def mecabFilename = "mecab-ko-dic-${mecabVersion}"
 
 task downloadDict(type: org.apache.lucene.gradle.Download) {
   sourceUrl = "https://bitbucket.org/eunjeon/mecab-ko-dic/downloads/${mecabFilename}.tar.gz"
-  target = new File("${buildDir}/${mecabFilename}.tar.gz")
+  target = mfile(buildDir, "${mecabFilename}.tar.gz")
   
   doLast {
-    ant.gunzip(src: "${buildDir}/${mecabFilename}.tar.gz")
-    ant.untar(src: "${buildDir}/${mecabFilename}.tar", dest: "${buildDir}")
+    ant.gunzip(src: filePath("${buildDir}/${mecabFilename}.tar.gz"))
+    ant.untar(src: filePath("${buildDir}/${mecabFilename}.tar"), dest: "${buildDir}")
   }
 }
 
 task buildNoriDict(type: JavaExec) {
   group = 'Build Regenerate'
-  description = "Downloads, patches, and builds dict for nori."
+  description = 'Downloads, patches, and builds dict for nori.'
   
   doFirst {
     def tree = fileTree("${projectDir}/org/apache/lucene/analysis/ko/dict")
@@ -83,8 +83,8 @@ task buildNoriDict(type: JavaExec) {
  
   jvmArgs '-Xmx1G'
 
-  args "${buildDir}/${mecabFilename}"
-  args "${projectDir}/src/resources"
+  args filePath("${buildDir}/${mecabFilename}")
+  args filePath("src/resources")
   args 'utf-8'
   args 'false'
   
diff --git a/lucene/analysis/opennlp/build.gradle b/lucene/analysis/opennlp/build.gradle
index 9d709d4..821f351 100644
--- a/lucene/analysis/opennlp/build.gradle
+++ b/lucene/analysis/opennlp/build.gradle
@@ -34,7 +34,7 @@ dependencies {
 task trainSentenceDetector(type: JavaExec) {
   
   doFirst {
-    new File("${projectDir}/src/tools/test-model-data").mkdirs()
+    mkdir("src/tools/test-model-data")
   }
   
   classpath = sourceSets.main.runtimeClasspath
@@ -44,9 +44,9 @@ task trainSentenceDetector(type: JavaExec) {
   args '-lang' 
   args 'en'
   args '-data' 
-  args "${projectDir}/src/tools/test-model-data/sentences.txt"
+  args filePath('src/tools/test-model-data/sentences.txt')
   args '-model'
-  args "${projectDir}/src/tools/test-model-data/en-test-sent.bin"
+  args filePath('src/tools/test-model-data/en-test-sent.bin')
   
   doLast {
     ant.copy(file: "${projectDir}/src/tools/test-model-data/en-test-sent.bin", todir: "${project.rootProject.projectDir}/solr/contrib/analysis-extras/src/test-files/analysis-extras/solr/collection1/conf")
@@ -57,7 +57,7 @@ task trainSentenceDetector(type: JavaExec) {
 task trainTokenizerTrainer(type: JavaExec) {
   
   doFirst {
-    new File("${projectDir}/src/tools/test-model-data").mkdirs()
+    mkdir("src/tools/test-model-data")
   }
   
   classpath = sourceSets.main.runtimeClasspath
@@ -67,12 +67,12 @@ task trainTokenizerTrainer(type: JavaExec) {
   args '-lang'
   args 'en'
   args '-data'
-  args "${projectDir}/src/tools/test-model-data/tokenizer.txt"
+  args filePath("src/tools/test-model-data/tokenizer.txt")
   args '-model'
-  args "${projectDir}/src/tools/test-model-data/en-test-tokenizer.bin"
+  args filePath("src/tools/test-model-data/en-test-tokenizer.bin")
   
   doLast {
-    ant.copy(file: "${projectDir}/src/tools/test-model-data/en-test-tokenizer.bin", todir: "${project.rootProject.projectDir}/solr/contrib/analysis-extras/src/test-files/analysis-extras/solr/collection1/conf")
+    ant.copy(file: filePath("src/tools/test-model-data/en-test-tokenizer.bin"), todir: filePath("${project.rootProject.projectDir}/solr/contrib/analysis-extras/src/test-files/analysis-extras/solr/collection1/conf"))
   }
 }
 
@@ -80,7 +80,7 @@ task trainTokenizerTrainer(type: JavaExec) {
 task trainPOSTaggerTrainer(type: JavaExec) {
   
   doFirst {
-    new File("${projectDir}/src/tools/test-model-data").mkdirs()
+    mkdir("src/tools/test-model-data")
   }
   
   classpath = sourceSets.main.runtimeClasspath
@@ -90,16 +90,16 @@ task trainPOSTaggerTrainer(type: JavaExec) {
   args '-lang'
   args 'en'
   args '-data'
-  args "${projectDir}/src/tools/test-model-data/pos.txt"
+  args filePath("src/tools/test-model-data/pos.txt")
   args '-model'
-  args "${projectDir}/src/tools/test-model-data/en-test-pos-maxent.bin"
+  args filePath("src/tools/test-model-data/en-test-pos-maxent.bin")
 }
 
 // https://opennlp.apache.org/docs/1.9.0/manual/opennlp.html#tools.chunker.training
 task trainChunkerTrainerME(type: JavaExec) {
   
   doFirst {
-    new File("${projectDir}/src/tools/test-model-data").mkdirs()
+    mkdir('src/tools/test-model-data')
   }
   
   classpath = sourceSets.main.runtimeClasspath
@@ -109,16 +109,16 @@ task trainChunkerTrainerME(type: JavaExec) {
   args '-lang'
   args 'en'
   args '-data'
-  args "${projectDir}/src/tools/test-model-data/chunks.txt"
+  args filePath('src/tools/test-model-data/chunks.txt')
   args '-model'
-  args "${projectDir}/src/tools/test-model-data/en-test-chunker.bin"
+  args filePath('src/tools/test-model-data/en-test-chunker.bin')
 }
 
 // https://opennlp.apache.org/docs/1.9.0/manual/opennlp.html#tools.namefind.training
 task trainTokenNameFinderTrainer(type: JavaExec) {
   
   doFirst {
-    new File("${projectDir}/src/tools/test-model-data").mkdirs()
+    mkdir('src/tools/test-model-data')
   }
   
   classpath = sourceSets.main.runtimeClasspath
@@ -128,11 +128,11 @@ task trainTokenNameFinderTrainer(type: JavaExec) {
   args '-lang'
   args 'en'
   args '-data'
-  args "${projectDir}/src/tools/test-model-data/ner.txt"
+  args filePath('src/tools/test-model-data/ner.txt')
   args '-model'
-  args "${projectDir}/src/tools/test-model-data/en-test-ner.bin"
+  args filePath('src/tools/test-model-data/en-test-ner.bin')
   args '-params'
-  args "${projectDir}/src/tools/test-model-data/ner_TrainerParams.txt"
+  args filePath('src/tools/test-model-data/ner_TrainerParams.txt')
   
   doLast {
     ant.copy(file: "${projectDir}/src/tools/test-model-data/en-test-ner.bin", todir: "${project.rootProject.projectDir}/solr/contrib/analysis-extras/src/test-files/analysis-extras/solr/collection1/conf")
@@ -143,7 +143,7 @@ task trainTokenNameFinderTrainer(type: JavaExec) {
 task trainLemmatizerTrainerME(type: JavaExec) {
   
   doFirst {
-    new File("${projectDir}/src/tools/test-model-data").mkdirs()
+    mkdir('src/tools/test-model-data')
   }
   
   classpath = sourceSets.main.runtimeClasspath
@@ -153,9 +153,9 @@ task trainLemmatizerTrainerME(type: JavaExec) {
   args '-lang'
   args 'en'
   args '-data'
-  args "${projectDir}/src/tools/test-model-data/lemmas.txt"
+  args filePath('src/tools/test-model-data/lemmas.txt')
   args '-model'
-  args "${projectDir}/src/tools/test-model-data/en-test-lemmatizer.bin"
+  args filePath('src/tools/test-model-data/en-test-lemmatizer.bin')
 }
 
 task trainTestModels {
@@ -167,4 +167,4 @@ task trainTestModels {
 
 task regenerate {
   dependsOn trainTestModels
-}
\ No newline at end of file
+}
diff --git a/lucene/analysis/smartcn/build.gradle b/lucene/analysis/smartcn/build.gradle
index 796f183..6d93b4e 100644
--- a/lucene/analysis/smartcn/build.gradle
+++ b/lucene/analysis/smartcn/build.gradle
@@ -23,8 +23,8 @@ archivesBaseName = 'lucene-analyzers-smartcn'
 
 dependencies {
   
-	implementation project(':lucene:lucene-core')
-	implementation project(':lucene:analysis:lucene-analyzers-common')
+  implementation project(':lucene:lucene-core')
+  implementation project(':lucene:analysis:lucene-analyzers-common')
   
-	testImplementation project(':lucene:lucene-test-framework')
+  testImplementation project(':lucene:lucene-test-framework')
 }
\ No newline at end of file
diff --git a/lucene/analysis/stempel/build.gradle b/lucene/analysis/stempel/build.gradle
index b0ad413..ee7c028 100644
--- a/lucene/analysis/stempel/build.gradle
+++ b/lucene/analysis/stempel/build.gradle
@@ -23,8 +23,8 @@ archivesBaseName = 'lucene-analyzers-stemple'
 
 dependencies {
   
-	implementation project(':lucene:lucene-core')
-	implementation project(':lucene:analysis:lucene-analyzers-common')
+  implementation project(':lucene:lucene-core')
+  implementation project(':lucene:analysis:lucene-analyzers-common')
   
-	testImplementation project(':lucene:lucene-test-framework')
+  testImplementation project(':lucene:lucene-test-framework')
 }
\ No newline at end of file
diff --git a/lucene/benchmark/build.gradle b/lucene/benchmark/build.gradle
index 81d8877..99e5738 100644
--- a/lucene/benchmark/build.gradle
+++ b/lucene/benchmark/build.gradle
@@ -14,12 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+ 
 apply plugin: 'java-library'
 apply plugin: 'maven-publish'
 apply plugin: org.apache.lucene.gradle.PartOfDist
 
-def workingDir = "${projectDir}/work"
+def workingDir = file("work")
 
 dependencies {
   
@@ -43,7 +43,7 @@ dependencies {
 // copy .alg files as resources for testing
 task copyConfResources(type: Copy) {
   from('conf')
-  into new File(sourceSets.test.java.outputDir, "conf")
+  into mfile(sourceSets.test.java.outputDir, "conf")
 }
 processTestResources.dependsOn copyConfResources
 
@@ -51,7 +51,7 @@ processTestResources.dependsOn copyConfResources
 
 task downloadEnwiki(type: org.apache.lucene.gradle.Download) {
   sourceUrl = "http://home.apache.org/~dsmiley/data/enwiki-20070527-pages-articles.xml.bz2"
-  target = new File("${projectDir}/temp/enwiki-20070527-pages-articles.xml.bz2")
+  target = file("temp/enwiki-20070527-pages-articles.xml.bz2")
 }
 
 task installEnwiki(){
@@ -68,14 +68,14 @@ installEnwiki.dependsOn downloadEnwiki
 
 task downloadGeoNames(type: org.apache.lucene.gradle.Download) {
   sourceUrl = "http://home.apache.org/~dsmiley/data/geonames_20130921_randomOrder_allCountries.txt.bz2"
-  target = new File("${projectDir}/temp/allCountries.txt.bz2")
+  target = mfile('temp', 'allCountries.txt.bz2')
 }
 
 task installGeoNames(){
   group = 'Benchmark Data'
   description = "Installs GeoNames data files."
   doLast {
-    new File("${workingDir}/geonames").mkdirs()
+    mkdir("${workingDir}/geonames")
     ant.bunzip2(src: "${projectDir}/temp/allCountries.txt.bz2", dest:"${workingDir}/geonames")
   }
   dependsOn downloadGeoNames
@@ -85,14 +85,14 @@ task installGeoNames(){
 
 task downloadReuters(type: org.apache.lucene.gradle.Download) {
   sourceUrl = "http://www.daviddlewis.com/resources/testcollections/reuters21578/reuters21578.tar.gz"
-  target = new File("${projectDir}/temp/reuters21578.tar.gz")
+  target = file("${projectDir}/temp/reuters21578.tar.gz")
 }
 
 task extractReuters(type: JavaExec) {
   classpath = sourceSets.main.runtimeClasspath
   main = 'org.apache.lucene.benchmark.utils.ExtractReuters'
-  args "${workingDir}/reuters"
-  args "${workingDir}/reuters-out"
+  args filePath("${workingDir}/reuters")
+  args filePath("${workingDir}/reuters-out")
   dependsOn downloadReuters
 }
 
@@ -100,9 +100,9 @@ task installReuters(){
   group = 'Benchmark Data'
   description = "Installs Reuters data files."
   doLast {
-    new File("${workingDir}/reuters").mkdirs()
-    ant.gunzip(src: "${projectDir}/temp/reuters21578.tar.gz", dest:"${projectDir}/temp/")
-    ant.untar(src: "${projectDir}/temp/reuters21578.tar", dest: "${workingDir}/reuters")
+    mkdir("${workingDir}/reuters")
+    ant.gunzip(src: filePath("${projectDir}/temp/reuters21578.tar.gz"), dest:"${projectDir}/temp/")
+    ant.untar(src: filePath("${projectDir}/temp/reuters21578.tar"), dest: "${workingDir}/reuters")
     def tree = fileTree("${workingDir}/reuters")
     tree.include '**/*.txt'
     tree.each { it.delete() }
diff --git a/lucene/build.gradle b/lucene/build.gradle
index a1d139d..603072e 100644
--- a/lucene/build.gradle
+++ b/lucene/build.gradle
@@ -3,13 +3,13 @@
  * 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 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,
+ * 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.
@@ -22,26 +22,25 @@ subprojects {
   group = 'org.apache.lucene'
 }
 
-def distDir = "dist"
+def distDir = 'dist'
 
-tasks.create("checkLicenses", LicenseCheckTask, new File(projectDir.getAbsolutePath()
-    + System.properties['file.separator'] + "licenses"))
+tasks.create('checkLicenses', LicenseCheckTask, file('licenses'))
 
-tasks.create("jarChecksums", JarChecksum, new File(project.rootProject.projectDir, "/lucene"), new File(project.rootProject.projectDir, "/lucene/licenses"))
+tasks.create('jarChecksums', JarChecksum, file('.'), file('licenses'))
 
 task packageDist(type: org.apache.lucene.gradle.PackageLuceneSolrDist) {
   group = 'Dist'
-  description = "Generates the Lucene and Solr distribution."
+  description = 'Generates the Lucene and Solr distribution.'
 }
 
 task runJflex() {
   group = 'Build Regenerate'
-  description = "Runs all jflex targets to regenerate src files."
+  description = 'Runs all jflex targets to regenerate src files.'
 }
 
 subprojects {
   File target = File.createTempDir()
-  tasks.create("jdepsReport", org.apache.lucene.gradle.JdepsReport, target)
-  tasks.create("unusedDeps", org.apache.lucene.gradle.UnusedDeps, target)
+  tasks.create('jdepsReport', org.apache.lucene.gradle.JdepsReport, target)
+  tasks.create('unusedDeps', org.apache.lucene.gradle.UnusedDeps, target)
   unusedDeps.dependsOn jdepsReport
 }
diff --git a/lucene/core/build.gradle b/lucene/core/build.gradle
index de2a88a..62a385a 100644
--- a/lucene/core/build.gradle
+++ b/lucene/core/build.gradle
@@ -31,12 +31,12 @@ dependencies {
 
 task downloadMoman(type: org.apache.lucene.gradle.Download) {
   sourceUrl = "${momanUrl}"
-  target = new File("${buildDir}", 'moman.zip')
+  target = mfile("${buildDir}", 'moman.zip')
 }
 
 task installMoman(){
   doLast {
-    ant.unzip(src: "${buildDir}/moman.zip", dest:"${buildDir}/moman", overwrite:"true") {
+    ant.unzip(src: filePath("${buildDir}/moman.zip"), dest: filePath("${buildDir}/moman"), overwrite:"true") {
       ant.cutdirsmapper(dirs: "1")
     }
   }
@@ -119,10 +119,10 @@ task runJflex(type: org.apache.lucene.gradle.JFlex) {
   group = 'Build Regenerate'
   description = "Runs jflex for StandardTokenizerImpl."
   
-  inputDir = new File("${projectDir}/src/java/org/apache/lucene/analysis/standard")
+  inputDir = file("src/java/org/apache/lucene/analysis/standard")
   fileName = "StandardTokenizerImpl"
   disableBufferExpansion = true
-  target = new File("${projectDir}/src/java/org/apache/lucene/analysis/standard")
+  target = file("src/java/org/apache/lucene/analysis/standard")
 }
 
 task cleanJflex() {
@@ -131,7 +131,7 @@ task cleanJflex() {
   
   doLast {
     ant.delete(failonerror: 'false') {
-      ant.fileset(dir: "src/java/org/apache/lucene/analysis/standard", includes: "**/*.java") {
+      ant.fileset(dir: file("src/java/org/apache/lucene/analysis/standard"), includes: "**/*.java") {
         ant.containsregexp(expression: "generated.*by.*JFlex")
       }
     }
diff --git a/lucene/queries/build.gradle b/lucene/queries/build.gradle
index 91be48f..37f70c3 100644
--- a/lucene/queries/build.gradle
+++ b/lucene/queries/build.gradle
@@ -20,9 +20,9 @@ apply plugin: 'maven-publish'
 apply plugin: org.apache.lucene.gradle.PartOfDist
 
 dependencies {
-	implementation project(':lucene:lucene-core')
-	implementation project(':lucene:lucene-codecs')
-	
-	testImplementation project(':lucene:lucene-test-framework')
-	testImplementation project(':lucene:lucene-expressions')
+  implementation project(':lucene:lucene-core')
+  implementation project(':lucene:lucene-codecs')
+  
+  testImplementation project(':lucene:lucene-test-framework')
+  testImplementation project(':lucene:lucene-expressions')
 }    
\ No newline at end of file
diff --git a/lucene/test-framework/build.gradle b/lucene/test-framework/build.gradle
index e8eb84a..23b028a 100644
--- a/lucene/test-framework/build.gradle
+++ b/lucene/test-framework/build.gradle
@@ -23,12 +23,12 @@ archivesBaseName = 'lucene-test-framework'
 
 dependencies {
   
-	api project(':lucene:lucene-core')
-	implementation project(':lucene:lucene-codecs')
+  api project(':lucene:lucene-core')
+  implementation project(':lucene:lucene-codecs')
   
-	api ("junit:junit")
+  api ("junit:junit")
   api ('org.hamcrest:hamcrest-core')
-	api ("com.carrotsearch.randomizedtesting:randomizedtesting-runner")
+  api ("com.carrotsearch.randomizedtesting:randomizedtesting-runner")
   api ('commons-codec:commons-codec')
   
 }
diff --git a/settings.gradle b/settings.gradle
index 148c77d..58b957c 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -31,9 +31,9 @@ include 'lucene:analysis:smartcn'
 project (':lucene:analysis:smartcn').name='lucene-analyzers-smartcn'
 include 'lucene:analysis:stempel'
 project (':lucene:analysis:stempel').name='lucene-analyzers-stempel'
-include	'lucene:backward-codecs'
+include  'lucene:backward-codecs'
 project (':lucene:backward-codecs').name='lucene-backward-codecs'
-include	'lucene:benchmark'
+include  'lucene:benchmark'
 project (':lucene:benchmark').name='lucene-benchmark'
 include 'lucene:classification'
 project (':lucene:classification').name='lucene-classification'
diff --git a/solr/build.gradle b/solr/build.gradle
index d05b0e4..59a96bf 100644
--- a/solr/build.gradle
+++ b/solr/build.gradle
@@ -24,14 +24,13 @@ subprojects {
 
 def distDir = "dist"
 
-tasks.create("checkLicenses", LicenseCheckTask, new File(projectDir.getAbsolutePath()
-    + System.properties['file.separator'] + "licenses"))
+tasks.create("checkLicenses", LicenseCheckTask, file("licenses"))
 
-tasks.create("jarChecksums", JarChecksum, new File(project.rootProject.projectDir, "/solr"), new File(project.rootProject.projectDir, "/solr/licenses"))
+tasks.create("jarChecksums", JarChecksum, file('solr'), file('licenses'))
 
 task packageDist(type: org.apache.lucene.gradle.PackageLuceneSolrDist) {
   group = 'Dist'
-  description = "Generates the Lucene and Solr distribution."
+  description = 'Generates the Lucene and Solr distribution.'
 }
 
 subprojects {
@@ -42,6 +41,6 @@ subprojects {
   unusedDeps.dependsOn jdepsReport
   
   unusedDeps.doLast {
-    deleteDirectory(target)
+    delete(target)
   }
 }
diff --git a/solr/core/build.gradle b/solr/core/build.gradle
index 824c869..4b5a266 100644
--- a/solr/core/build.gradle
+++ b/solr/core/build.gradle
@@ -209,7 +209,7 @@ forbiddenApisTest {
   exclude 'org/apache/hadoop/**'
 }
 
-task javacc(type: org.apache.lucene.gradle.JavaCC) {
-  inputFile file("${projectDir}/src/java/org/apache/solr/parser/QueryParser.jj")
-  target file("${projectDir}/src/java/org/apache/lucene/analysis/standard")
+task javacc(type: org.apache.lucene.gradle.SolrQPJavaCC) {
+  inputFile file('src/java/org/apache/solr/parser/QueryParser.jj')
+  target file('src/java/org/apache/solr/parser')
 }


[lucene-solr] 02/05: SOLR-13452: Set tools src to UTF-8.

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

markrmiller pushed a commit to branch jira/SOLR-13452_gradle_3
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 7466b119ac1bf8996332295426d278ac852f617b
Author: markrmiller <ma...@apache.org>
AuthorDate: Thu Jun 6 14:33:05 2019 -0500

    SOLR-13452: Set tools src to UTF-8.
---
 lucene/analysis/icu/build.gradle      | 2 ++
 lucene/analysis/kuromoji/build.gradle | 5 +++++
 lucene/analysis/nori/build.gradle     | 5 +++++
 3 files changed, 12 insertions(+)

diff --git a/lucene/analysis/icu/build.gradle b/lucene/analysis/icu/build.gradle
index a0de8b7..2f9fdf8 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/analysis/icu/build.gradle
@@ -43,6 +43,8 @@ sourceSets {
   tools.java.srcDirs = ['src/tools/java']
 }
 
+compileToolsJava.options.encoding = "UTF-8"
+
 task genUtr30DataFiles(type: JavaExec) {
   group = 'Build Regenerate'
   description = "Compiles UTR30 rules."
diff --git a/lucene/analysis/kuromoji/build.gradle b/lucene/analysis/kuromoji/build.gradle
index 5580098..0543e67 100644
--- a/lucene/analysis/kuromoji/build.gradle
+++ b/lucene/analysis/kuromoji/build.gradle
@@ -49,6 +49,11 @@ sourceSets {
   toolsTest.java.srcDirs = ['src/tools/test']
 }
 
+compileToolsJava.options.encoding = "UTF-8"
+compileToolsTestJava.options.encoding = "UTF-8"
+
+
+
 def ipadicVersion = "2.7.0-20070801"
 def ipadicFilename = "mecab-ipadic-${ipadicVersion}"
 
diff --git a/lucene/analysis/nori/build.gradle b/lucene/analysis/nori/build.gradle
index 2550ea2..a636c8e 100644
--- a/lucene/analysis/nori/build.gradle
+++ b/lucene/analysis/nori/build.gradle
@@ -48,6 +48,11 @@ sourceSets {
   toolsTest.java.srcDirs = ['src/tools/test']
 }
 
+
+compileToolsJava.options.encoding = "UTF-8"
+compileToolsTestJava.options.encoding = "UTF-8"
+
+
 def mecabVersion = "2.0.3-20170922"
 def mecabFilename = "mecab-ko-dic-${mecabVersion}"
 


[lucene-solr] 01/05: SOLR-13452: Improve unused dep checker: break it up into jdep and unused tasks, output improvements, etc.

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

markrmiller pushed a commit to branch jira/SOLR-13452_gradle_3
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit a94e430ca551ae67b6b8f88880c9de3104c02941
Author: markrmiller <ma...@apache.org>
AuthorDate: Thu Jun 6 11:53:11 2019 -0500

    SOLR-13452: Improve unused dep checker: break it up into jdep and unused tasks, output improvements, etc.
---
 .../org/apache/lucene/gradle/JdepsReport.groovy    | 166 +++++++++++++++++++
 .../org/apache/lucene/gradle/UnusedDeps.groovy     | 177 +++++++++------------
 lucene/build.gradle                                |   6 +-
 lucene/test-framework/build.gradle                 |   3 +-
 solr/build.gradle                                  |   5 +-
 solr/contrib/clustering/build.gradle               |   2 -
 solr/contrib/dataimporthandler/build.gradle        |  12 +-
 solr/core/build.gradle                             |   2 +-
 8 files changed, 254 insertions(+), 119 deletions(-)

diff --git a/buildSrc/src/main/groovy/org/apache/lucene/gradle/JdepsReport.groovy b/buildSrc/src/main/groovy/org/apache/lucene/gradle/JdepsReport.groovy
new file mode 100644
index 0000000..5c48e2b
--- /dev/null
+++ b/buildSrc/src/main/groovy/org/apache/lucene/gradle/JdepsReport.groovy
@@ -0,0 +1,166 @@
+package org.apache.lucene.gradle
+/*
+ * 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.api.artifacts.ResolvedArtifact
+import org.gradle.api.artifacts.ResolvedDependency
+import org.gradle.api.artifacts.result.DependencyResult
+import org.gradle.api.artifacts.result.ResolvedDependencyResult
+
+import javax.inject.Inject
+
+import org.apache.tools.ant.types.resources.selectors.InstanceOf
+import org.gradle.api.DefaultTask
+import org.gradle.api.Project
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.artifacts.Dependency
+import org.gradle.api.artifacts.ModuleIdentifier
+import org.gradle.api.file.RelativePath
+import org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency
+import org.gradle.api.specs.Spec
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.Optional
+import org.gradle.api.tasks.InputDirectory
+import org.gradle.api.tasks.InputFile
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.tasks.TaskAction
+
+import java.nio.file.Files
+import java.util.regex.Matcher
+import java.util.regex.Pattern
+
+class JdepsReport extends DefaultTask {
+  
+  protected configuration = "runtimeClasspath"
+
+  protected File distDir
+  protected File jdepsDir
+  
+  @OutputDirectory
+  File target
+
+  @Inject
+  public JdepsReport(File target) {
+    if (!project.configurations.hasProperty('runtimeClasspath')) {
+      return
+    }
+
+    this.target = target
+    
+    doFirst {
+      println "Writing output files to ${target}"
+    }
+    
+    if (project.hasProperty('unusedDepsConfig')) {
+      configuration = project.unusedDepsConfig
+    }
+    
+    Configuration config = project.configurations[this.configuration]
+    
+    List<Project> buildProjects = new ArrayList()
+    buildProjects.add(project)
+    config.getAllDependencies().forEach({ dep ->
+      if (dep instanceof DefaultProjectDependency) {
+        Project dProject = dep.getDependencyProject()
+        buildProjects.add(dProject)
+      }
+    })
+    
+    project.tasks.create(name: "depsToDir", type: org.gradle.api.tasks.Copy) {
+      outputs.upToDateWhen { false }
+      into({ makeDirs(); distDir })
+      buildProjects.each {subproject ->
+        project.evaluationDependsOn(subproject.path)
+        def topLvlProject = getTopLvlProject(subproject)
+        
+        if (subproject.getPlugins().hasPlugin(PartOfDist) && subproject.tasks.findByName('jar') && subproject.configurations.hasProperty('runtimeClasspath')) {
+           from(subproject.jar.outputs.files) {
+            include "*.jar"
+            into ({topLvlProject.name + '/' + topLvlProject.relativePath(subproject.projectDir)})
+          }
+          def files = { getFiles(subproject) }
+          from(files) {
+            include "*.jar"
+            into ({topLvlProject.name + '/' + topLvlProject.relativePath(subproject.projectDir) + "/lib"})
+          }
+        }
+      }
+      
+      includeEmptyDirs = false
+    }
+    
+    dependsOn project.tasks.depsToDir
+  }
+  
+  protected void makeDirs() {
+    target.mkdirs()
+    distDir = new File(target, 'distDir')
+    jdepsDir = new File(target, 'jdepsDir')
+    distDir.mkdirs()
+    jdepsDir.mkdirs()
+  }
+
+  
+  @TaskAction
+  void execute() {
+    // make sure ant task logging shows up by default
+    ant.lifecycleLogLevel = "INFO"
+
+    runJdeps(getTopLvlProject(project), project, distDir, jdepsDir)
+    
+    Configuration config = project.configurations[this.configuration]
+    config.getAllDependencies().forEach({ dep ->
+      if (dep instanceof DefaultProjectDependency) {
+        Project dProject = dep.getDependencyProject()
+        def depTopLvlProject = getTopLvlProject(dProject)
+        
+        runJdeps(depTopLvlProject, dProject, distDir, jdepsDir)
+      }
+    })
+  }
+  
+  protected void runJdeps(Project topLvlProject, Project project, File distDir, File jdepsDir) {
+    def distPath = "${distDir}/" + topLvlProject.name + "/" + topLvlProject.relativePath(project.projectDir)
+    def dotOutPath = jdepsDir.getAbsolutePath() + "/" + topLvlProject.name +  "/" + "${project.name}-${project.version}"
+    
+    ant.exec (executable: "jdeps", failonerror: true, resolveexecutable: true) {
+      ant.arg(line: '--class-path ' + "${distPath}/lib/" + '*')
+      ant.arg(line: '--multi-release 11')
+      ant.arg(value: '-verbose:class')
+      ant.arg(line: "-dotoutput ${dotOutPath}")
+      ant.arg(value: "${distPath}/${project.name}-${project.version}.jar")
+    }
+  }
+  
+  private static Collection getFiles(Project subproject) {
+    def files = subproject.configurations.runtimeClasspath.files
+    
+    return files
+  }
+  
+  protected Project getTopLvlProject(Project proj) {
+    def topLvlProject
+    if (proj.group ==~ /.*?\.lucene(?:\.\w+)?/) {
+      topLvlProject = project.project(":lucene")
+    } else if (proj.group ==~ /.*?\.solr(?:\.\w+)?/) {
+      topLvlProject = project.project(":solr")
+    }
+    return topLvlProject
+  }
+}
+
+
diff --git a/buildSrc/src/main/groovy/org/apache/lucene/gradle/UnusedDeps.groovy b/buildSrc/src/main/groovy/org/apache/lucene/gradle/UnusedDeps.groovy
index aed0703..fe6fd53 100644
--- a/buildSrc/src/main/groovy/org/apache/lucene/gradle/UnusedDeps.groovy
+++ b/buildSrc/src/main/groovy/org/apache/lucene/gradle/UnusedDeps.groovy
@@ -17,13 +17,15 @@ package org.apache.lucene.gradle
  */
 
 import org.gradle.api.artifacts.ResolvedArtifact
-
+import org.gradle.api.artifacts.ResolvedDependency
 import javax.inject.Inject
 import org.gradle.api.DefaultTask
 import org.gradle.api.Project
 import org.gradle.api.artifacts.Configuration
+import org.gradle.api.artifacts.Dependency
 import org.gradle.api.file.RelativePath
 import org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency
+import org.gradle.api.specs.Spec
 import org.gradle.api.tasks.Input
 import org.gradle.api.tasks.Optional
 import org.gradle.api.tasks.InputDirectory
@@ -40,16 +42,24 @@ class UnusedDeps extends DefaultTask {
   protected static Pattern pattern = Pattern.compile("\\(([^\\s]*?\\.jar)\\)")
   
   protected configuration = "runtimeClasspath"
-  protected File tmpDir
   protected File distDir
   protected File jdepsDir
   
-  public UnusedDeps() {
-    //!project.getPlugins().hasPlugin('java-base') ||
+  @InputDirectory
+  File inputDirectory
+  
+  @Inject
+  public UnusedDeps(File inputDirectory) {
+    
     if (!project.configurations.hasProperty('runtimeClasspath')) {
       return
     }
     
+    this.inputDirectory = inputDirectory
+    
+    distDir = new File(inputDirectory, 'distDir')
+    jdepsDir = new File(inputDirectory, 'jdepsDir')
+    
     if (project.hasProperty('unusedDepsConfig')) {
       configuration = project.unusedDepsConfig
     }
@@ -64,61 +74,6 @@ class UnusedDeps extends DefaultTask {
         buildProjects.add(dProject)
       }
     })
-    
-    project.tasks.create(name: "export", type: org.gradle.api.tasks.Copy) {
-      outputs.upToDateWhen { false }
-      into({ makeDirs(); distDir })
-      buildProjects.each {subproject ->
-        project.evaluationDependsOn(subproject.path)
-        def topLvlProject
-        if (subproject.group ==~ /.*?\.lucene(?:\.\w+)?/) {
-          topLvlProject = project.project(":lucene")
-        } else if (subproject.group ==~ /.*?\.solr(?:\.\w+)?/) {
-          topLvlProject = project.project(":solr")
-        }
-        
-        if (subproject.getPlugins().hasPlugin(PartOfDist) && subproject.tasks.findByName('jar') && subproject.configurations.hasProperty('runtimeClasspath')) {
-          from(subproject.jar.outputs.files) {
-            include "*.jar"
-            into ({topLvlProject.name + '/' + topLvlProject.relativePath(subproject.projectDir)})
-          }
-          def files = { getFiles(subproject) }
-          from(files) {
-            include "*.jar"
-            into ({topLvlProject.name + '/' + topLvlProject.relativePath(subproject.projectDir) + "/lib"})
-          }
-        }
-      }
-      
-      includeEmptyDirs = false
-    }
-    
-    dependsOn project.tasks.export
-  }
-  
-  protected void makeDirs() {
-    tmpDir = File.createTempDir()
-    tmpDir.deleteOnExit()
-    tmpDir.mkdirs()
-    distDir = new File(tmpDir, 'distDir')
-    jdepsDir = new File(tmpDir, 'jdepsDir')
-    distDir.mkdirs()
-    jdepsDir.mkdirs()
-  }
-  
-  private static Collection getFiles(Project subproject) {
-    def files = subproject.configurations.runtimeClasspath.files
-    if (!subproject.name.equals('solr-core') && subproject.path.startsWith(":solr:contrib:")) {
-      subproject.evaluationDependsOn(subproject.rootProject.project(":solr:solr-core").path)
-      files = files - subproject.rootProject.project(":solr:solr-core").configurations.runtimeClasspath.files
-      files = files - subproject.rootProject.project(":solr:solr-core").jar.outputs.files
-    }
-    if (!subproject.name.equals('lucene-core') && subproject.path.startsWith(":lucene:")) {
-      subproject.evaluationDependsOn(subproject.rootProject.project(":lucene:lucene-core").path)
-      files = files - subproject.rootProject.project(":lucene:lucene-core").configurations.runtimeClasspath.files
-      files = files - subproject.rootProject.project(":lucene:lucene-core").jar.outputs.files
-    }
-    return files
   }
   
   @TaskAction
@@ -126,40 +81,30 @@ class UnusedDeps extends DefaultTask {
     // make sure ant task logging shows up by default
     ant.lifecycleLogLevel = "INFO"
     
-    Project topLvlProject
-    
-    if (project.group ==~ /.*?\.lucene(?:\.\w+)?/) {
-      topLvlProject = project.project(":lucene")
-    } else if (project.group ==~ /.*?\.solr(?:\.\w+)?/) {
-      topLvlProject = project.project(":solr")
-    }
-    
-    def luceneDist  = new File("/data1/mark/tmp", "lucene")
-    def solrDist = new File("/data1/mark/tmp", "solr")
+    def topLvlProject = getTopLvlProject(project)
     
     Configuration config = project.configurations[this.configuration]
     
-    Set<String> usedDepJarNames = getDirectlyUsedDeps(topLvlProject, project, distDir, jdepsDir)
+    Set<String> usedDepJarNames = getDefinedDeps(topLvlProject, project, distDir, jdepsDir)
+    
+    Set<File> ourDeps = getAllDefinedDeps(project, config)
     
-    Set<File> ourDeps = getDeps(project, config)
+    Set<File> ourImmediatelyDefinedDeps = getOurImmediateDefinedDeps(project, config)
     
     config.getAllDependencies().forEach({ dep ->
       if (dep instanceof DefaultProjectDependency) {
         Project dProject = dep.getDependencyProject()
-        def depTopLvlProject
-        if (dProject.group ==~ /.*?\.lucene(?:\.\w+)?/) {
-          depTopLvlProject = project.project(":lucene")
-        } else if (dProject.group ==~ /.*?\.solr(?:\.\w+)?/) {
-          depTopLvlProject = project.project(":solr")
-        }
+        def depTopLvlDProject = getTopLvlProject(dProject)
         
-        Set<String> projectUsedDeps = getDirectlyUsedDeps(depTopLvlProject, dProject, distDir, jdepsDir)
+        Set<String> projectUsedDeps = getDefinedDeps(depTopLvlDProject, dProject, distDir, jdepsDir)
         
         usedDepJarNames += projectUsedDeps
       }
     })
     
-    usedDepJarNames -= ["${project.name}-${project.version}.jar"]
+    usedDepJarNames -= [
+      "${project.name}-${project.version}.jar"
+    ]
     
     Set<String> ourDepJarNames = new HashSet<>()
     ourDeps.forEach( { ourDepJarNames.add(it.getName()) } )
@@ -169,64 +114,80 @@ class UnusedDeps extends DefaultTask {
     unusedJarNames -= usedDepJarNames
     unusedJarNames = unusedJarNames.toSorted()
     
-    Set<String> foundDeps = new HashSet<>()
+    Set<String> depsInDirectUse = new HashSet<>()
     
     File jdepsLucene = new File(jdepsDir, "lucene")
     File jdepsSolr = new File(jdepsDir, "solr")
     
     for (File file : jdepsLucene.listFiles()) {
-      lookForDep(file, foundDeps)
+      lookForDep(file, depsInDirectUse)
     }
     for (File file : jdepsSolr.listFiles()) {
-      lookForDep(file, foundDeps)
+      lookForDep(file, depsInDirectUse)
     }
     
     println ''
     println 'Our classpath dependency count ' + ourDepJarNames.size()
     println 'Our directly used dependency count ' + usedDepJarNames.size()
     println ''
-    println 'List of possibly unused jars - they may be used at runtime however (Class.forName or something), this is not definitive.'
-    println 'We take our classpath dependenies, substract our direct dependencies and then subtract dependencies used by our direct dependencies'
+    println 'List of possibly unused jars - they may be used at runtime however (Class.forName on plugins or config text for example). This is not definitive, but helps narrow down what to investigate.'
+    println 'We take our classpath dependencies, substract our direct dependencies and then subtract dependencies used by our direct dependencies.'
     println ''
     
+    println 'Direct deps that may be unused:'
     unusedJarNames.forEach({
-      if (!foundDeps.contains(it)) {
-        println it
+      if (!depsInDirectUse.contains(it) && ourImmediatelyDefinedDeps.contains(it)) {
+        println ' - ' + it
       }
     })
     
-    project.delete(tmpDir)
+    println ''
+    println 'Deps brought in by other modules that may be unused in this module:'
+    unusedJarNames.forEach({
+      if (!depsInDirectUse.contains(it) && !ourImmediatelyDefinedDeps.contains(it)) {
+        println ' - ' + it
+      }
+    })
   }
   
-  protected Set getDeps(Project project, Configuration config) {
+  static class NonProjectSpec implements Spec<Dependency> {
+    @Override
+    public boolean isSatisfiedBy(Dependency dep) {
+      return true
+    }
+  }
+  
+  protected Set getAllDefinedDeps(Project project, Configuration config) {
     Set<File> ourDeps = new HashSet<>()
     
     if (config.isCanBeResolved()) {
       config.getResolvedConfiguration().getResolvedArtifacts().forEach( { ra -> ourDeps.add(ra.getFile()) })
     }
+    
     return ourDeps
   }
   
-  protected Set getDirectlyUsedDeps(Project topLvlProject, Project project, File distDir, File jdepsDir) {
-    def distPath = "${distDir}/" + topLvlProject.name + "/" + topLvlProject.relativePath(project.projectDir)
-    def dotOutPath = jdepsDir.getAbsolutePath() + "/" + topLvlProject.name +  "/" + "${project.name}-${project.version}"
+  protected Set getOurImmediateDefinedDeps(Project project, Configuration config) {
+    Set<String> ourDeps = new HashSet<>()
     
-    ant.exec (executable: "jdeps", failonerror: true, resolveexecutable: true) {
-      ant.arg(line: '--class-path ' + "${distPath}/lib/" + '*')
-      ant.arg(line: '--multi-release 11')
-      ant.arg(value: '-recursive')
-      ant.arg(value: '-verbose:class')
-      ant.arg(line: "-dotoutput ${dotOutPath}")
-      ant.arg(value: "${distPath}/${project.name}-${project.version}.jar")
+    Set<ResolvedDependency> deps = project.configurations.runtimeClasspath.getResolvedConfiguration().getFirstLevelModuleDependencies(new NonProjectSpec())
+    
+    for (ResolvedDependency dep : deps) {
+      dep.getModuleArtifacts().forEach({ourDeps.add(it.file.name)})
     }
     
+    return ourDeps
+  }
+  
+  protected Set getDefinedDeps(Project topLvlProject, Project project, File distDir, File jdepsDir) {
+    
     File dotFile = new File(jdepsDir, topLvlProject.name +  "/" + "${project.name}-${project.version}/${project.name}-${project.version}.jar.dot")
-    Set<String> usedDepJarNames = getUsedJars(project, dotFile)
+    Set<String> usedDepJarNames = getDirectlyUsedJars(project, dotFile)
     
     return usedDepJarNames
   }
   
-  protected Set getUsedJars(Project project, File dotFile) {
+  protected Set getDirectlyUsedJars(Project project, File dotFile) {
     Set<String> usedDepJarNames = new HashSet<>()
     
     def lines = dotFile.readLines()
@@ -244,12 +205,20 @@ class UnusedDeps extends DefaultTask {
     return usedDepJarNames
   }
   
-  protected void lookForDep(File dir, Set<String> foundDeps) {
+  protected void lookForDep(File dir, Set<String> depsInDirectUse) {
     dir.eachFile() {
-      Set<String> usedDepJarNames = getUsedJars(project, it)
-      foundDeps.addAll(usedDepJarNames)
-      
+      depsInDirectUse.addAll(getDirectlyUsedJars(project, it))
+    }
+  }
+  
+  protected Project getTopLvlProject(Project proj) {
+    def topLvlProject
+    if (proj.group ==~ /.*?\.lucene(?:\.\w+)?/) {
+      topLvlProject = project.project(":lucene")
+    } else if (proj.group ==~ /.*?\.solr(?:\.\w+)?/) {
+      topLvlProject = project.project(":solr")
     }
+    return topLvlProject
   }
 }
 
diff --git a/lucene/build.gradle b/lucene/build.gradle
index cb8d785..a1d139d 100644
--- a/lucene/build.gradle
+++ b/lucene/build.gradle
@@ -40,6 +40,8 @@ task runJflex() {
 }
 
 subprojects {
-  tasks.create("unusedDeps", org.apache.lucene.gradle.UnusedDeps)
-  unusedDeps.dependsOn packageDist
+  File target = File.createTempDir()
+  tasks.create("jdepsReport", org.apache.lucene.gradle.JdepsReport, target)
+  tasks.create("unusedDeps", org.apache.lucene.gradle.UnusedDeps, target)
+  unusedDeps.dependsOn jdepsReport
 }
diff --git a/lucene/test-framework/build.gradle b/lucene/test-framework/build.gradle
index 8c52c46..e8eb84a 100644
--- a/lucene/test-framework/build.gradle
+++ b/lucene/test-framework/build.gradle
@@ -29,7 +29,6 @@ dependencies {
 	api ("junit:junit")
   api ('org.hamcrest:hamcrest-core')
 	api ("com.carrotsearch.randomizedtesting:randomizedtesting-runner")
-
-  implementation ('commons-codec:commons-codec')
+  api ('commons-codec:commons-codec')
   
 }
diff --git a/solr/build.gradle b/solr/build.gradle
index 9325c49..9ea77bc 100644
--- a/solr/build.gradle
+++ b/solr/build.gradle
@@ -35,5 +35,8 @@ task packageDist(type: org.apache.lucene.gradle.PackageLuceneSolrDist) {
 }
 
 subprojects {
-  tasks.create("unusedDeps", org.apache.lucene.gradle.UnusedDeps)
+  File target = File.createTempDir()
+  tasks.create("jdepsReport", org.apache.lucene.gradle.JdepsReport, target)
+  tasks.create("unusedDeps", org.apache.lucene.gradle.UnusedDeps, target)
+  unusedDeps.dependsOn jdepsReport
 }
diff --git a/solr/contrib/clustering/build.gradle b/solr/contrib/clustering/build.gradle
index 217133f..44e1210 100644
--- a/solr/contrib/clustering/build.gradle
+++ b/solr/contrib/clustering/build.gradle
@@ -24,14 +24,12 @@ dependencies {
   implementation project(':solr:solr-core')
   implementation project(':solr:solr-solrj')
   implementation project(':lucene:lucene-core')
-  implementation project(':lucene:lucene-memory')
   implementation project(':lucene:analysis:lucene-analyzers-common')
   
   implementation ('org.slf4j:slf4j-api')
   implementation ('org.carrot2:carrot2-mini')
   implementation ('org.carrot2.shaded:carrot2-guava')
   implementation ('org.carrot2.attributes:attributes-binder')
-  implementation ('org.simpleframework:simple-xml')
   implementation ('com.fasterxml.jackson.core:jackson-annotations')
   implementation ('com.fasterxml.jackson.core:jackson-databind')
   implementation ('commons-io:commons-io')
diff --git a/solr/contrib/dataimporthandler/build.gradle b/solr/contrib/dataimporthandler/build.gradle
index fe99459..a673846 100644
--- a/solr/contrib/dataimporthandler/build.gradle
+++ b/solr/contrib/dataimporthandler/build.gradle
@@ -41,20 +41,18 @@ dependencies {
   implementation project(':lucene:lucene-join')
   
   implementation ('org.slf4j:slf4j-api') { transitive = false }
-  implementation ('com.google.guava:guava') { transitive = false }
   implementation ('commons-io:commons-io') { transitive = false }
   implementation ('org.apache.httpcomponents:httpclient') { transitive = false }
   implementation ('org.apache.zookeeper:zookeeper') { transitive = false }
   implementation ('io.dropwizard.metrics:metrics-core') { transitive = false }
-  implementation ('commons-codec:commons-codec') { transitive = false }
   
   testImplementation project(':lucene:lucene-test-framework')
   testImplementation project(':solr:solr-test-framework')
   
-  testImplementation 'org.hsqldb:hsqldb'
-  testImplementation 'org.apache.derby:derby'
-  testImplementation 'org.mockito:mockito-core'
-  testImplementation 'net.bytebuddy:byte-buddy'
-  testImplementation 'org.objenesis:objenesis'
+  testImplementation ('org.mockito:mockito-core')
+  testImplementation ('org.hsqldb:hsqldb')
+  testImplementation ('org.apache.derby:derby')
+  testImplementation ('net.bytebuddy:byte-buddy')
+  testImplementation ('org.objenesis:objenesis')
   
 }
\ No newline at end of file
diff --git a/solr/core/build.gradle b/solr/core/build.gradle
index a40a87e..ffd12ca 100644
--- a/solr/core/build.gradle
+++ b/solr/core/build.gradle
@@ -25,10 +25,10 @@ archivesBaseName = 'solr-core'
 
 dependencies {
   
+  runtimeOnly project(':lucene:analysis:lucene-analyzers-phonetic')
   implementation project(':lucene:lucene-core')
   implementation project(':lucene:lucene-codecs')
   implementation project(':lucene:analysis:lucene-analyzers-common')
-  implementation project(':lucene:analysis:lucene-analyzers-phonetic')
   implementation project(':lucene:analysis:lucene-analyzers-kuromoji')
   implementation project(':lucene:analysis:lucene-analyzers-nori')
   implementation project(':lucene:lucene-suggest')