You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by dw...@apache.org on 2021/12/19 11:05:20 UTC
[lucene] 01/03: Revert "Reverting back to 9d19b49038b."
This is an automated email from the ASF dual-hosted git repository.
dweiss pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/lucene.git
commit c3d3d0703b1b4b027e411a3f474a75825a144dd7
Author: Dawid Weiss <da...@carrotsearch.com>
AuthorDate: Sun Dec 19 11:59:13 2021 +0100
Revert "Reverting back to 9d19b49038b."
This reverts commit d2a022f49bb84a409c96307febd314da6eb22353.
---
build.gradle | 9 +-
gradle/documentation/render-javadoc.gradle | 68 +++--
gradle/ide/eclipse.gradle | 6 +-
gradle/ide/intellij-idea.gradle | 2 +-
gradle/java/jar-manifest.gradle | 32 ---
gradle/java/javac.gradle | 3 +-
gradle/java/modules-debugging.gradle | 84 ++++++
gradle/java/modules.gradle | 254 ++++++++++++++++++
gradle/maven/publications.gradle | 10 +-
gradle/testing/randomization.gradle | 4 +-
gradle/validation/ecj-lint.gradle | 60 ++++-
gradle/validation/ecj-lint/ecj.javadocs.prefs | 8 +-
lucene/CHANGES.txt | 3 +
lucene/analysis/common/build.gradle | 2 +-
lucene/analysis/common/src/java/module-info.java | 222 ++++++++++++++++
lucene/analysis/icu/build.gradle | 6 +-
lucene/analysis/icu/src/java/module-info.java | 37 +++
lucene/analysis/kuromoji/build.gradle | 4 +-
lucene/analysis/kuromoji/src/java/module-info.java | 40 +++
.../{kuromoji => morfologik.tests}/build.gradle | 11 +-
.../src/test/module-info.java} | 18 +-
.../morfologik/tests/TestMorfologikAnalyzer.java | 47 ++++
lucene/analysis/morfologik/build.gradle | 11 +-
.../{build.gradle => src/java/module-info.java} | 24 +-
.../analysis/uk/UkrainianMorfologikAnalyzer.java | 104 +++++---
lucene/analysis/nori/build.gradle | 4 +-
.../src/java/module-info.java} | 22 +-
lucene/analysis/opennlp/build.gradle | 6 +-
.../src/java/module-info.java} | 23 +-
lucene/analysis/phonetic/build.gradle | 6 +-
.../src/java/module-info.java} | 23 +-
lucene/analysis/smartcn/build.gradle | 4 +-
.../src/java/module-info.java} | 17 +-
lucene/analysis/stempel/build.gradle | 4 +-
.../src/java/module-info.java} | 18 +-
lucene/backward-codecs/build.gradle | 4 +-
lucene/backward-codecs/src/java/module-info.java | 47 ++++
lucene/benchmark/build.gradle | 24 +-
lucene/benchmark/src/java/module-info.java | 40 +++
lucene/classification/build.gradle | 6 +-
.../src/java/module-info.java} | 18 +-
lucene/codecs/build.gradle | 2 +-
lucene/codecs/src/java/module-info.java | 39 +++
lucene/core/src/java/module-info.java | 72 +++++
lucene/demo/build.gradle | 12 +-
.../src/java/module-info.java} | 24 +-
lucene/distribution.tests/build.gradle | 62 +++++
.../lucene/distribution/TestModularLayer.java | 295 +++++++++++++++++++++
lucene/distribution/binary-release.gradle | 59 +++--
.../distribution/src/binary-release/bin/luke.cmd | 2 +-
lucene/distribution/src/binary-release/bin/luke.sh | 2 +-
lucene/expressions/build.gradle | 17 +-
.../src/java/module-info.java} | 19 +-
lucene/facet/build.gradle | 6 +-
.../src/java/module-info.java} | 25 +-
lucene/grouping/build.gradle | 4 +-
.../src/java/module-info.java} | 12 +-
lucene/highlighter/build.gradle | 6 +-
.../src/java/module-info.java} | 19 +-
lucene/join/build.gradle | 2 +-
.../src/java/module-info.java} | 11 +-
lucene/licenses/asm-analysis-7.2.jar.sha1 | 1 +
lucene/licenses/asm-tree-7.2.jar.sha1 | 1 +
lucene/licenses/assertj-core-3.21.0.jar.sha1 | 1 +
lucene/licenses/assertj-core-LICENSE-ASL.txt | 201 ++++++++++++++
lucene/licenses/assertj-core-NOTICE.txt | 0
lucene/luke/build.gradle | 53 ++--
.../src/java/module-info.java} | 20 +-
.../apache/lucene/luke/app/desktop/LukeMain.java | 30 ++-
.../lucene/luke/app/desktop/util/FontUtils.java | 6 +-
.../app/desktop/{font => util}/ElegantIcons.ttf | Bin
lucene/memory/build.gradle | 2 +-
.../src/java/module-info.java} | 11 +-
lucene/misc/build.gradle | 2 +-
.../src/java/module-info.java} | 20 +-
lucene/monitor/build.gradle | 6 +-
.../src/java/module-info.java} | 14 +-
lucene/queries/build.gradle | 2 +-
.../src/java/module-info.java} | 24 +-
lucene/queryparser/build.gradle | 6 +-
lucene/queryparser/src/java/module-info.java | 52 ++++
lucene/replicator/build.gradle | 8 +-
.../src/java/module-info.java} | 20 +-
lucene/sandbox/build.gradle | 4 +-
.../src/java/module-info.java} | 23 +-
lucene/spatial-extras/build.gradle | 10 +-
.../src/java/module-info.java} | 28 +-
lucene/spatial3d/build.gradle | 2 +-
.../src/java/module-info.java} | 12 +-
lucene/suggest/build.gradle | 4 +-
lucene/suggest/src/java/module-info.java | 36 +++
settings.gradle | 8 +-
versions.lock | 5 +-
versions.props | 3 +-
94 files changed, 2142 insertions(+), 498 deletions(-)
diff --git a/build.gradle b/build.gradle
index bf2f34d..220ada7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -110,6 +110,10 @@ apply from: file('buildSrc/scriptDepVersions.gradle')
apply from: file('gradle/generation/local-settings.gradle')
+// IDE support, settings and specials.
+apply from: file('gradle/ide/intellij-idea.gradle')
+apply from: file('gradle/ide/eclipse.gradle')
+
// Set up defaults and configure aspects for certain modules or functionality
// (java, tests)
apply from: file('gradle/java/folder-layout.gradle')
@@ -119,14 +123,11 @@ apply from: file('gradle/testing/randomization.gradle')
apply from: file('gradle/testing/fail-on-no-tests.gradle')
apply from: file('gradle/testing/alternative-jdk-support.gradle')
apply from: file('gradle/java/jar-manifest.gradle')
+apply from: file('gradle/java/modules.gradle')
// Maven artifact publishing.
apply from: file('gradle/maven/publications.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/measure-task-times.gradle')
apply from: file('gradle/validation/error-prone.gradle')
diff --git a/gradle/documentation/render-javadoc.gradle b/gradle/documentation/render-javadoc.gradle
index 11499be..9579c5d 100644
--- a/gradle/documentation/render-javadoc.gradle
+++ b/gradle/documentation/render-javadoc.gradle
@@ -59,20 +59,28 @@ allprojects {
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;
-
- relativeProjectLinks = true
-
- // Place the documentation under Lucene or Solr's documentation directory.
- // docroot is defined in 'documentation.gradle'
- outputDir = project.docroot.toPath().resolve(project.relativeDocPath).toFile()
+ if (project.path == ':lucene:luke' || project.path.endsWith(".tests")) {
+ // These projects are not part of the public API so we don't render their javadocs
+ // as part of the site's creation. A side-effect of this is that javadocs would not
+ // be linted for these projects. To avoid this, we connect the regular javadoc task
+ // to check so that everything is validated.
+ project.tasks.getByName("check").dependsOn renderJavadoc
+ } else {
+ 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
+
+ relativeProjectLinks = true
+
+ // Place the documentation under the documentation directory.
+ // docroot is defined in 'documentation.gradle'
+ outputDir = project.docroot.toPath().resolve(project.relativeDocPath).toFile()
+ }
}
}
}
@@ -257,10 +265,6 @@ configure(subprojects) {
}
}
-configure(project(':lucene:luke')) {
- project.tasks.matching { it.name == 'renderSiteJavadoc' }.configureEach { it.enabled = false }
-}
-
class RenderJavadocTask extends DefaultTask {
@InputFiles
@SkipWhenEmpty
@@ -329,16 +333,18 @@ class RenderJavadocTask extends DefaultTask {
@TaskAction
public void render() {
- def srcDirs = srcDirSet.srcDirs.findAll { dir -> dir.exists() }
+ def srcDirs = srcDirSet.sourceDirectories.filter { dir -> dir.exists() }
+
def optionsFile = project.file("${getTemporaryDir()}/javadoc-options.txt")
// create the directory, so relative link calculation knows that it's a directory:
outputDir.mkdirs();
def opts = []
- opts << [ '-overview', project.file("${srcDirs[0]}/overview.html") ]
- opts << [ '-sourcepath', srcDirs.join(File.pathSeparator) ]
- opts << [ '-subpackages', project.path.startsWith(':lucene') ? 'org.apache.lucene' : 'org.apache.solr' ]
+
+ def overviewSourceSetDir = srcDirs.filter { dir -> project.file("${dir}/overview.html").exists() }.singleFile
+ opts << [ '-overview', project.file("${overviewSourceSetDir}/overview.html") ]
+
opts << [ '-d', outputDir ]
opts << '-protected'
opts << [ '-encoding', 'UTF-8' ]
@@ -430,6 +436,24 @@ class RenderJavadocTask extends DefaultTask {
def jOpts = opts.findAll { opt -> opt instanceof String && opt.startsWith("-J") }
opts.removeAll(jOpts)
+ // Collect all source files, for now excluding module descriptors.
+ opts.addAll(
+ srcDirs.collectMany { dir ->
+ project.fileTree(dir: dir, include: "**/*.java", exclude: "**/module-info.java").files
+ }.collect { it.toString() }
+ )
+
+ // handle doc-files manually since in explicit source file mode javadoc does not copy them.
+ srcDirs.each { File dir ->
+ project.copy {
+ into outputDir
+
+ from(dir, {
+ include "**/doc-files/**"
+ })
+ }
+ }
+
// Temporary file that holds all javadoc options for the current task (except jOpts)
optionsFile.withWriter("UTF-8", { writer ->
// escapes an option with single quotes or whitespace to be passed in the options.txt file for
diff --git a/gradle/ide/eclipse.gradle b/gradle/ide/eclipse.gradle
index 0a5b608..4db9ae3 100644
--- a/gradle/ide/eclipse.gradle
+++ b/gradle/ide/eclipse.gradle
@@ -58,7 +58,11 @@ configure(rootProject) {
jars += prj.configurations.testCompileClasspath.resolve()
}
- classpath.entries += sources.sort().collect {name -> new SourceFolder(name, "build/eclipse/" + name) }
+ classpath.entries += sources.sort().collect { name ->
+ def sourceFolder = new SourceFolder(name, "build/eclipse/" + name)
+ sourceFolder.setExcludes(["module-info.java"])
+ return sourceFolder
+ }
classpath.entries += jars.unique().findAll { location -> location.isFile() }.collect { location ->
new LibEntry(location.toString())
}
diff --git a/gradle/ide/intellij-idea.gradle b/gradle/ide/intellij-idea.gradle
index 1d5b8d2..589aaec 100644
--- a/gradle/ide/intellij-idea.gradle
+++ b/gradle/ide/intellij-idea.gradle
@@ -16,7 +16,7 @@
*/
// Try to detect IntelliJ model loader ("reimport") early.
-def isIdea = System.getProperty("idea.active") != null ||
+rootProject.ext.isIdea = System.getProperty("idea.active") != null ||
gradle.startParameter.taskNames.contains('idea') ||
gradle.startParameter.taskNames.contains('cleanIdea')
diff --git a/gradle/java/jar-manifest.gradle b/gradle/java/jar-manifest.gradle
index d4ab812..359b579 100644
--- a/gradle/java/jar-manifest.gradle
+++ b/gradle/java/jar-manifest.gradle
@@ -69,12 +69,6 @@ subprojects {
"X-Build-OS" : "${System.properties['os.name']} ${System.properties['os.arch']} ${System.properties['os.version']}"
]
- // Only apply automatic module name to jar task.
- if (task.name in ["jar"]) {
- manifestAttrs["Automatic-Module-Name"] =
- "${-> project.path.replaceFirst(/^:lucene/, Matcher.quoteReplacement(project.group)).replace(':', '.').replace('-', '_')}"
- }
-
manifest {
attributes(manifestAttrs)
}
@@ -88,29 +82,3 @@ subprojects {
}
}
}
-
-configure(rootProject) {
- tasks.register("showModuleNames", { showModuleTask ->
- def allJarTasks = []
-
- rootProject.subprojects.each { subproject ->
- subproject.tasks.matching { it.name == 'jar' }.all {
- allJarTasks.add it
- }
- }
-
- dependsOn allJarTasks
-
- doFirst {
- allJarTasks.each { jarTask ->
- File jarFile = jarTask.outputs.files.singleFile
- try (def jar = new JarFile(jarFile)) {
- logger.lifecycle(String.format(Locale.ROOT,
- "%-50s -> %s",
- jarFile.name,
- jar.manifest.mainAttributes.getValue("Automatic-Module-Name")))
- }
- }
- }
- })
-}
diff --git a/gradle/java/javac.gradle b/gradle/java/javac.gradle
index 78c5fb4..25f66c3 100644
--- a/gradle/java/javac.gradle
+++ b/gradle/java/javac.gradle
@@ -39,7 +39,8 @@ allprojects {
"-Xlint:dep-ann",
"-Xlint:divzero",
"-Xlint:empty",
- "-Xlint:exports",
+ // TODO: uh-oh we have broken APIs.
+ "-Xlint:-exports",
"-Xlint:fallthrough",
"-Xlint:finally",
"-Xlint:opens",
diff --git a/gradle/java/modules-debugging.gradle b/gradle/java/modules-debugging.gradle
new file mode 100644
index 0000000..52bc6fe
--- /dev/null
+++ b/gradle/java/modules-debugging.gradle
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Debugging/ validation utilities and helpers to aid transition
+// to java modules.
+
+allprojects {
+ plugins.withType(JavaPlugin) {
+ // Show all non-empty package names
+ tasks.register("showPackageNames", { task ->
+ doFirst {
+ listPackageNames(sourceSets).each { println(it) }
+ }
+ })
+
+ tasks.register("showServiceProviders", { task ->
+ doFirst {
+ def services = listServices(sourceSets)
+ services.each { entry -> {
+ println(entry.key)
+ entry.value.each { println(" ${it}") }
+ }}
+ }
+ })
+ }
+}
+
+/* Utility method to collect all package names in a source sets. */
+static def listPackageNames(SourceSetContainer sourceSets) {
+ var pkgNameSet = [] as Set<String>
+ sourceSets.main.each { sourceSet ->
+ var dirs = sourceSet.allJava.srcDirTrees.collect { it.dir.toPath() }
+ var pattern = new PatternSet()
+ .include('**/*.java')
+ .exclude('module-info.java')
+ .exclude('**/package-info.java')
+ sourceSet.allJava.matching(pattern).each {srcFile ->
+ var srcPath = srcFile.toPath()
+ var dir = dirs.find { srcPath.startsWith(it) }
+ var pkgName = srcPath.subpath(dir.nameCount, srcPath.nameCount).parent.stream().map(Object::toString).collect(Collectors.joining('.'))
+ pkgNameSet.add(pkgName)
+ }
+ }
+ var pkgNames = pkgNameSet as List<String>
+ pkgNames.sort()
+ return pkgNames
+}
+
+/* Utility method to collect all service providers in a source sets. */
+static def listServices(SourceSetContainer sourceSets) {
+ def services = [:] as Map<String, List<String>>
+ sourceSets.main.each {sourceSet ->
+ var pattern = new PatternSet().include('META-INF/services/*')
+ sourceSet.resources.matching(pattern).each {file ->
+ def serviceName = file.name
+ def providers = []
+ file.withReader { reader -> {
+ reader.lines().each { l ->
+ def line = l.trim()
+ if (line != "" && !line.startsWith("#")) {
+ def provider = line.replace('$', '.')
+ providers.add(provider)
+ }
+ }
+ }}
+ services.put(serviceName, providers)
+ }
+ }
+ return services
+}
diff --git a/gradle/java/modules.gradle b/gradle/java/modules.gradle
new file mode 100644
index 0000000..45405a2
--- /dev/null
+++ b/gradle/java/modules.gradle
@@ -0,0 +1,254 @@
+/*
+ * 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.
+ */
+
+// Configure miscellaneous aspects required for supporting the java module system layer.
+
+allprojects {
+ plugins.withType(JavaPlugin) {
+ // We won't be using gradle's built-in automatic module finder.
+ java {
+ modularity.inferModulePath.set(false)
+ }
+
+ // Map convention configuration names to "modular" corresponding configurations.
+ Closure<String> moduleConfigurationNameFor = { String configurationName ->
+ return "module" + configurationName.capitalize().replace("Classpath", "Path")
+ }
+
+ //
+ // For each source set, create explicit configurations for declaring modular dependencies.
+ // These "modular" configurations correspond 1:1 to Gradle's conventions but have a 'module' prefix
+ // and a capitalized remaining part of the conventional name. For example, an 'api' configuration in
+ // the main source set would have a corresponding 'moduleApi' configuration for declaring modular
+ // dependencies.
+ //
+ // Gradle's java plugin "convention" configurations extend from their modular counterparts
+ // so all dependencies end up on classpath by default for backward compatibility with other
+ // tasks and gradle infrastructure.
+ //
+ // At the same time, we also know which dependencies (and their transitive graph of dependencies!)
+ // should be placed on module-path only.
+ //
+ // Note that an explicit configuration of modular dependencies also opens up the possibility of automatically
+ // validating whether the dependency configuration for a gradle project is consistent with the information in
+ // the module-info descriptor because there is a (nearly?) direct correspondence between the two:
+ //
+ // moduleApi - 'requires transitive'
+ // moduleImplementation - 'requires'
+ // moduleCompileOnly - 'requires static'
+ //
+ project.sourceSets.all { SourceSet sourceSet ->
+ ConfigurationContainer configurations = project.configurations
+
+ // Create modular configurations for convention configurations.
+ Closure<Configuration> createModuleConfigurationForConvention = { String configurationName ->
+ Configuration conventionConfiguration = configurations.maybeCreate(configurationName)
+ Configuration moduleConfiguration = configurations.maybeCreate(moduleConfigurationNameFor(configurationName))
+ moduleConfiguration.canBeConsumed(false)
+ moduleConfiguration.canBeResolved(false)
+ conventionConfiguration.extendsFrom(moduleConfiguration)
+
+ project.logger.info("Created module configuration for '${conventionConfiguration.name}': ${moduleConfiguration.name}")
+ return moduleConfiguration
+ }
+
+ Configuration moduleApi = createModuleConfigurationForConvention(sourceSet.apiConfigurationName)
+ Configuration moduleImplementation = createModuleConfigurationForConvention(sourceSet.implementationConfigurationName)
+ moduleImplementation.extendsFrom(moduleApi)
+ Configuration moduleRuntimeOnly = createModuleConfigurationForConvention(sourceSet.runtimeOnlyConfigurationName)
+ Configuration moduleCompileOnly = createModuleConfigurationForConvention(sourceSet.compileOnlyConfigurationName)
+ // sourceSet.compileOnlyApiConfigurationName // This seems like a very esoteric use case, leave out.
+
+ // Set up compilation module path configuration combining corresponding convention configurations.
+ Closure<Configuration> createResolvableModuleConfiguration = { String configurationName ->
+ Configuration conventionConfiguration = configurations.maybeCreate(configurationName)
+ Configuration moduleConfiguration = configurations.maybeCreate(
+ moduleConfigurationNameFor(conventionConfiguration.name))
+ moduleConfiguration.canBeConsumed(false)
+ moduleConfiguration.canBeResolved(true)
+ moduleConfiguration.attributes {
+ // Prefer class folders over JARs. The exception is made for tests projects which require a composition
+ // of classes and resources, otherwise split into two folders.
+ if (project.name.endsWith(".tests")) {
+ attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements, LibraryElements.JAR))
+ } else {
+ attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements, LibraryElements.CLASSES))
+ }
+ }
+
+ project.logger.info("Created resolvable module configuration for '${conventionConfiguration.name}': ${moduleConfiguration.name}")
+ return moduleConfiguration
+ }
+
+ Configuration compileModulePathConfiguration = createResolvableModuleConfiguration(sourceSet.compileClasspathConfigurationName)
+ compileModulePathConfiguration.extendsFrom(moduleCompileOnly, moduleImplementation)
+
+ Configuration runtimeModulePathConfiguration = createResolvableModuleConfiguration(sourceSet.runtimeClasspathConfigurationName)
+ runtimeModulePathConfiguration.extendsFrom(moduleRuntimeOnly, moduleImplementation)
+
+ // Create and register a source set extension for manipulating classpath/ module-path
+ ModularPathsExtension modularPaths = new ModularPathsExtension(project, sourceSet,
+ compileModulePathConfiguration,
+ runtimeModulePathConfiguration)
+ sourceSet.extensions.add("modularPaths", modularPaths)
+
+ // Customized the JavaCompile for this source set so that it has proper module path.
+ tasks.named(sourceSet.getCompileJavaTaskName()).configure({ JavaCompile task ->
+ task.dependsOn modularPaths.compileModulePathConfiguration
+
+ // Add modular dependencies and their transitive dependencies to module path.
+ task.options.compilerArgumentProviders.add((CommandLineArgumentProvider) {
+ def modularPathFiles = modularPaths.compileModulePathConfiguration.files
+ def extraArgs = []
+ if (!modularPathFiles.isEmpty()) {
+ if (!modularPaths.hasModuleDescriptor()) {
+ // We're compiling a non-module so we'll bring everything on module path in
+ // otherwise things wouldn't be part of the resolved module graph.
+ extraArgs += ["--add-modules", "ALL-MODULE-PATH"]
+ }
+
+ extraArgs += ["--module-path", modularPathFiles.join(File.pathSeparator)]
+ }
+
+ task.logger.info("Module path for ${task.path}:\n " + modularPathFiles.sort().join("\n "))
+
+ return extraArgs
+ })
+
+ // LUCENE-10304: if we modify the classpath here, IntelliJ no longer sees the dependencies as compile-time
+ // dependencies, don't know why.
+ if (!rootProject.ext.isIdea) {
+ // Modify the default classpath by removing anything already placed on module path.
+ // This could be done in a fancier way but a set difference is just fine for us here. Use a lazy
+ // provider to delay computation of the actual path.
+ task.classpath = files({ ->
+ def trimmedClasspath = sourceSet.compileClasspath - modularPaths.compileModulePathConfiguration
+ task.logger.info("Class path for ${task.path}:\n " + trimmedClasspath.files.sort().join("\n "))
+ return trimmedClasspath
+ })
+ }
+ })
+ }
+
+ //
+ // Configure the (default) test task to use module paths.
+ //
+ // There is no explicit connection between source sets and test tasks so there is no way (?)
+ // to do this automatically, convention-style.
+
+ // This closure can be used to configure a different task, with a different source set, should we
+ // have the need for it.
+ Closure<Void> configureTestTaskForSourceSet = { Test task, SourceSet sourceSet ->
+ task.configure {
+ Configuration modulePath = task.project.configurations.maybeCreate(
+ moduleConfigurationNameFor(sourceSet.getRuntimeClasspathConfigurationName()))
+
+ task.dependsOn modulePath
+
+ // Add modular dependencies and their transitive dependencies to module path.
+ task.jvmArgumentProviders.add((CommandLineArgumentProvider) {
+ def extraArgs = []
+
+ // Determine whether the source set classes themselves should be appended
+ // to classpath or module path.
+ boolean sourceSetIsAModule = sourceSet.modularPaths.hasModuleDescriptor()
+
+ if (!modulePath.isEmpty() || sourceSetIsAModule) {
+ if (sourceSetIsAModule) {
+ // Add source set outputs to module path.
+ extraArgs += ["--module-path", (modulePath + sourceSet.output.classesDirs).files.join(File.pathSeparator)]
+ // Ideally, we should only add the sourceset's module here, everything else would be resolved via the
+ // module descriptor. But this would require parsing the module descriptor and may cause JVM version conflicts
+ // so keeping it simple.
+ extraArgs += ["--add-modules", "ALL-MODULE-PATH"]
+ } else {
+ extraArgs += ["--module-path", modulePath.files.join(File.pathSeparator)]
+ // In this case we're running a non-module against things on the module path so let's bring in
+ // everything on module path into the resolution graph.
+ extraArgs += ["--add-modules", "ALL-MODULE-PATH"]
+ }
+ }
+
+ task.logger.info("Module path for ${task.path}:\n " + modulePath.files.sort().join("\n "))
+
+ return extraArgs
+ })
+
+
+ // Modify the default classpath by removing anything already placed on module path.
+ // This could be done in a fancier way but a set difference is just fine for us here. Use a lazy
+ // provider to delay computation of the actual path.
+ task.classpath = files({ ->
+ def trimmedClasspath = sourceSet.runtimeClasspath - modulePath
+
+ boolean sourceSetIsAModule = sourceSet.modularPaths.hasModuleDescriptor()
+ if (sourceSetIsAModule) {
+ // also subtract the sourceSet's output directories.
+ trimmedClasspath = trimmedClasspath - sourceSet.output.classesDirs
+ }
+
+ task.logger.info("Class path for ${task.path}:\n " + trimmedClasspath.files.sort().join("\n "))
+ return trimmedClasspath
+ })
+ }
+ }
+
+ // Configure (tasks.test, sourceSets.test)
+ tasks.matching { it.name == "test" }.all { Test task ->
+ configureTestTaskForSourceSet(task, task.project.sourceSets.test)
+ }
+
+ // Configure module versions.
+ tasks.withType(JavaCompile).configureEach { task ->
+ // TODO: LUCENE-10267: workaround for gradle bug. Remove when the corresponding issue is fixed.
+ task.options.compilerArgumentProviders.add((CommandLineArgumentProvider) { ->
+ if (task.getClasspath().isEmpty()) {
+ return ["--module-version", project.version.toString()]
+ } else {
+ return []
+ }
+ })
+
+ task.options.javaModuleVersion.set(provider {
+ return project.version.toString()
+ })
+ }
+ }
+}
+
+
+class ModularPathsExtension {
+ Project project
+ SourceSet sourceSet
+ Configuration compileModulePathConfiguration
+ Configuration runtimeModulePathConfiguration
+
+ ModularPathsExtension(Project project, SourceSet sourceSet,
+ Configuration compileModulePathConfiguration,
+ Configuration runtimeModulePathConfiguration) {
+ this.project = project
+ this.sourceSet = sourceSet
+ this.compileModulePathConfiguration = compileModulePathConfiguration
+ this.runtimeModulePathConfiguration = runtimeModulePathConfiguration
+ }
+
+ boolean hasModuleDescriptor() {
+ return sourceSet.allJava.srcDirs.stream()
+ .map(dir -> new File(dir, "module-info.java"))
+ .anyMatch(file -> file.exists())
+ }
+}
\ No newline at end of file
diff --git a/gradle/maven/publications.gradle b/gradle/maven/publications.gradle
index 32422cd..cc9bc96 100644
--- a/gradle/maven/publications.gradle
+++ b/gradle/maven/publications.gradle
@@ -31,15 +31,19 @@
configure(rootProject) {
ext {
mavenProjects = project(":lucene").subprojects.findAll {subproject ->
- return !(subproject.path in [
- // Exclude distribution assembly & documentation.
+ def excluded = [
+ // Exclude distribution assembly, tests & documentation.
":lucene:distribution",
":lucene:documentation",
// Exclude the parent container project for analysis modules (no artifacts).
":lucene:analysis",
// Exclude the native module.
":lucene:misc:native"
- ])
+ ]
+
+ // Exclude all subprojects that are modular test projects and those explicitly
+ // excluded above.
+ return !(subproject.path.endsWith(".tests") || subproject.path in excluded)
}
}
}
diff --git a/gradle/testing/randomization.gradle b/gradle/testing/randomization.gradle
index fc6c991..938ca39 100644
--- a/gradle/testing/randomization.gradle
+++ b/gradle/testing/randomization.gradle
@@ -164,7 +164,9 @@ allprojects {
// Enable security manager, if requested. We could move the selection of security manager and security policy
// to each project's build/ configuration but it seems compact enough to keep it here for now.
if (Boolean.parseBoolean(testOptionsResolved["tests.useSecurityManager"])) {
- if (project.path == ":lucene:replicator") {
+ if (project.path.endsWith(".tests")) {
+ // LUCENE-10301: for now, do not use the security manager for modular tests (test framework is not available).
+ } else if (project.path == ":lucene:replicator") {
systemProperty 'java.security.manager', "org.apache.lucene.util.TestSecurityManager"
systemProperty 'java.security.policy', file("${resources}/policies/replicator-tests.policy")
} else if (project.path.startsWith(":lucene")) {
diff --git a/gradle/validation/ecj-lint.gradle b/gradle/validation/ecj-lint.gradle
index 398c26e..591eb84 100644
--- a/gradle/validation/ecj-lint.gradle
+++ b/gradle/validation/ecj-lint.gradle
@@ -35,9 +35,10 @@ allprojects {
// with a non-empty java.srcDirs. These tasks are then
// attached to project's "ecjLint" task.
def lintTasks = sourceSets.collect { sourceSet ->
- def srcDirs = sourceSet.java.srcDirs.findAll { dir -> dir.exists() }
+ def srcDirs = sourceSet.java.sourceDirectories
+ .filter { dir -> dir.exists() }
- tasks.create(sourceSet.getTaskName("ecjLint", null), JavaExec, {task ->
+ tasks.create(sourceSet.getTaskName("ecjLint", null), JavaExec, {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
@@ -60,6 +61,24 @@ allprojects {
def tmpDst = getTemporaryDir()
workingDir tmpDst
+ // Place input files in an external file to dodge command line argument
+ // limits. We could pass a directory but ecj seems to be buggy: when it
+ // encounters a module-info.java file it no longer compiles other source files.
+ def inputsFile = file("${tmpDst}/ecj-inputs.txt")
+ // escape filename accoring to ECJ's rules:
+ // https://github.com/eclipse/aspectj.eclipse.jdt.core/blob/a05312e746b9bc2b48b4b039f6e7b5e061b5b393/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java#L1533-L1537
+ // Basically surround all whitespace by quotes:
+ def escapeFileName = { String s -> s.replaceAll(/ +/, /"$0"/) }
+ inputsFile.setText(
+ srcDirs.collectMany { dir ->
+ project.fileTree(dir: dir, include: "**/*.java" ).files
+ }
+ // Try to sort all input files; a side-effect of this should be that module-info.java
+ // is placed first on the list, which works around ECJ bug:
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=569833
+ .sort()
+ .collect {file -> escapeFileName(file.absolutePath.toString())}.join("\n"), "UTF-8")
+
args += [ "-d", "none" ]
// Compilation environment.
@@ -72,22 +91,41 @@ allprojects {
args += [ "-enableJavadoc" ]
args += [ "-properties", file("${resources}/ecj.javadocs.prefs").absolutePath ]
- doFirst {
- tmpDst.mkdirs()
+ // We depend on modular paths.
+ def modularPaths = sourceSet.modularPaths
+ dependsOn modularPaths.compileModulePathConfiguration
+
+ task.argumentProviders.add((CommandLineArgumentProvider) {
+ // Add modular dependencies and their transitive dependencies to module path.
+ def modularPathFiles = modularPaths.compileModulePathConfiguration.files
+ def extraArgs = []
+ if (!modularPathFiles.isEmpty()) {
+ if (!modularPaths.hasModuleDescriptor()) {
+ // We're compiling a non-module so we'll bring everything on module path in
+ // otherwise things wouldn't be part of the resolved module graph.
+ extraArgs += ["--add-modules", "ALL-MODULE-PATH"]
+ }
+
+ extraArgs += ["--module-path", modularPathFiles.join(File.pathSeparator)]
+ }
- // Add classpath locations at execution time (can't resolve the
+ // Add classpath locations in a lazy provider (can't resolve the
// configuration at evaluation time). Filter out non-existing entries
// (output folders for non-existing input source dirs like resources).
def cpath = sourceSet.compileClasspath.filter { p -> p.exists() }
+ cpath = cpath - modularPathFiles
if (!cpath.isEmpty()) {
- args += ["-classpath", cpath.asPath]
+ extraArgs += ["-classpath", cpath.join(File.pathSeparator)]
}
- // Add source location(s). Ideally we'd provide a set of files as in:
- // args += sourceSet.java.files
- // but this exceeds max allowed command line size. So we pass source
- // directories instead:
- args += srcDirs
+ // Add source location(s) in an external file to avoid command line argument limits.
+ extraArgs += ["@" + inputsFile.absolutePath]
+
+ return extraArgs
+ })
+
+ doFirst {
+ tmpDst.mkdirs()
}
})
}
diff --git a/gradle/validation/ecj-lint/ecj.javadocs.prefs b/gradle/validation/ecj-lint/ecj.javadocs.prefs
index a5352aa..25d527a 100644
--- a/gradle/validation/ecj-lint/ecj.javadocs.prefs
+++ b/gradle/validation/ecj-lint/ecj.javadocs.prefs
@@ -17,7 +17,8 @@ org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
-org.eclipse.jdt.core.compiler.problem.APILeak=error
+# TODO: disabled because we do have api leaks in modules
+org.eclipse.jdt.core.compiler.problem.APILeak=ignore
org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated=error
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
@@ -120,7 +121,8 @@ org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=error
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=error
+# TODO: ideally, we shouldn't rely on these... but we do.
+org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
@@ -144,4 +146,4 @@ org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=11
org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
org.eclipse.jdt.core.compiler.taskPriorities=HIGH
-org.eclipse.jdt.core.compiler.taskTags=nocommit
+org.eclipse.jdt.core.compiler.taskTags=nocommit
\ No newline at end of file
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 6460edd..0584b68 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -14,6 +14,9 @@ API Changes
New Features
---------------------
+* LUCENE-10255: Lucene JARs are now proper modules, with module descriptors and dependency information.
+ (Chris Hegarty, Uwe Schindler, Tomoko Uchida, Dawid Weiss)
+
* LUCENE-10223: Add interval function support to StandardQueryParser. Add min-should-match operator
support to StandardQueryParser. Update and clean up package documentation in flexible query parser
module. (Dawid Weiss, Alan Woodward)
diff --git a/lucene/analysis/common/build.gradle b/lucene/analysis/common/build.gradle
index 6fba70a..1815041 100644
--- a/lucene/analysis/common/build.gradle
+++ b/lucene/analysis/common/build.gradle
@@ -20,7 +20,7 @@ apply plugin: 'java-library'
description = 'Analyzers for indexing content in different languages and domains'
dependencies {
- api project(':lucene:core')
+ moduleApi project(':lucene:core')
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/analysis/common/src/java/module-info.java b/lucene/analysis/common/src/java/module-info.java
new file mode 100644
index 0000000..e736a95
--- /dev/null
+++ b/lucene/analysis/common/src/java/module-info.java
@@ -0,0 +1,222 @@
+/*
+ * 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 Analysis Common. */
+module org.apache.lucene.analysis.common {
+ requires java.xml;
+ requires org.apache.lucene.core;
+
+ exports org.apache.lucene.analysis.ar;
+ exports org.apache.lucene.analysis.bg;
+ exports org.apache.lucene.analysis.bn;
+ exports org.apache.lucene.analysis.boost;
+ exports org.apache.lucene.analysis.br;
+ exports org.apache.lucene.analysis.ca;
+ exports org.apache.lucene.analysis.charfilter;
+ exports org.apache.lucene.analysis.cjk;
+ exports org.apache.lucene.analysis.ckb;
+ exports org.apache.lucene.analysis.classic;
+ exports org.apache.lucene.analysis.commongrams;
+ exports org.apache.lucene.analysis.compound.hyphenation;
+ exports org.apache.lucene.analysis.compound;
+ exports org.apache.lucene.analysis.core;
+ exports org.apache.lucene.analysis.custom;
+ exports org.apache.lucene.analysis.cz;
+ exports org.apache.lucene.analysis.da;
+ exports org.apache.lucene.analysis.de;
+ exports org.apache.lucene.analysis.el;
+ exports org.apache.lucene.analysis.email;
+ exports org.apache.lucene.analysis.en;
+ exports org.apache.lucene.analysis.es;
+ exports org.apache.lucene.analysis.et;
+ exports org.apache.lucene.analysis.eu;
+ exports org.apache.lucene.analysis.fa;
+ exports org.apache.lucene.analysis.fi;
+ exports org.apache.lucene.analysis.fr;
+ exports org.apache.lucene.analysis.ga;
+ exports org.apache.lucene.analysis.gl;
+ exports org.apache.lucene.analysis.hi;
+ exports org.apache.lucene.analysis.hu;
+ exports org.apache.lucene.analysis.hunspell;
+ exports org.apache.lucene.analysis.hy;
+ exports org.apache.lucene.analysis.id;
+ exports org.apache.lucene.analysis.in;
+ exports org.apache.lucene.analysis.it;
+ exports org.apache.lucene.analysis.lt;
+ exports org.apache.lucene.analysis.lv;
+ exports org.apache.lucene.analysis.minhash;
+ exports org.apache.lucene.analysis.miscellaneous;
+ exports org.apache.lucene.analysis.ne;
+ exports org.apache.lucene.analysis.ngram;
+ exports org.apache.lucene.analysis.nl;
+ exports org.apache.lucene.analysis.no;
+ exports org.apache.lucene.analysis.path;
+ exports org.apache.lucene.analysis.pattern;
+ exports org.apache.lucene.analysis.payloads;
+ exports org.apache.lucene.analysis.pt;
+ exports org.apache.lucene.analysis.query;
+ exports org.apache.lucene.analysis.reverse;
+ exports org.apache.lucene.analysis.ro;
+ exports org.apache.lucene.analysis.ru;
+ exports org.apache.lucene.analysis.shingle;
+ exports org.apache.lucene.analysis.sinks;
+ exports org.apache.lucene.analysis.snowball;
+ exports org.apache.lucene.analysis.sr;
+ exports org.apache.lucene.analysis.sv;
+ exports org.apache.lucene.analysis.synonym;
+ exports org.apache.lucene.analysis.ta;
+ exports org.apache.lucene.analysis.te;
+ exports org.apache.lucene.analysis.th;
+ exports org.apache.lucene.analysis.tr;
+ exports org.apache.lucene.analysis.util;
+ exports org.apache.lucene.analysis.wikipedia;
+ exports org.apache.lucene.collation.tokenattributes;
+ exports org.apache.lucene.collation;
+ exports org.tartarus.snowball.ext;
+ exports org.tartarus.snowball;
+
+ provides org.apache.lucene.analysis.CharFilterFactory with
+ org.apache.lucene.analysis.charfilter.HTMLStripCharFilterFactory,
+ org.apache.lucene.analysis.charfilter.MappingCharFilterFactory,
+ org.apache.lucene.analysis.cjk.CJKWidthCharFilterFactory,
+ org.apache.lucene.analysis.fa.PersianCharFilterFactory,
+ org.apache.lucene.analysis.pattern.PatternReplaceCharFilterFactory;
+ provides org.apache.lucene.analysis.TokenFilterFactory with
+ org.apache.lucene.analysis.tr.ApostropheFilterFactory,
+ org.apache.lucene.analysis.ar.ArabicNormalizationFilterFactory,
+ org.apache.lucene.analysis.ar.ArabicStemFilterFactory,
+ org.apache.lucene.analysis.bg.BulgarianStemFilterFactory,
+ org.apache.lucene.analysis.boost.DelimitedBoostTokenFilterFactory,
+ org.apache.lucene.analysis.bn.BengaliNormalizationFilterFactory,
+ org.apache.lucene.analysis.bn.BengaliStemFilterFactory,
+ org.apache.lucene.analysis.br.BrazilianStemFilterFactory,
+ org.apache.lucene.analysis.cjk.CJKBigramFilterFactory,
+ org.apache.lucene.analysis.cjk.CJKWidthFilterFactory,
+ org.apache.lucene.analysis.ckb.SoraniNormalizationFilterFactory,
+ org.apache.lucene.analysis.ckb.SoraniStemFilterFactory,
+ org.apache.lucene.analysis.classic.ClassicFilterFactory,
+ org.apache.lucene.analysis.commongrams.CommonGramsFilterFactory,
+ org.apache.lucene.analysis.commongrams.CommonGramsQueryFilterFactory,
+ org.apache.lucene.analysis.compound.DictionaryCompoundWordTokenFilterFactory,
+ org.apache.lucene.analysis.compound.HyphenationCompoundWordTokenFilterFactory,
+ org.apache.lucene.analysis.core.DecimalDigitFilterFactory,
+ org.apache.lucene.analysis.core.LowerCaseFilterFactory,
+ org.apache.lucene.analysis.core.StopFilterFactory,
+ org.apache.lucene.analysis.core.TypeTokenFilterFactory,
+ org.apache.lucene.analysis.core.UpperCaseFilterFactory,
+ org.apache.lucene.analysis.cz.CzechStemFilterFactory,
+ org.apache.lucene.analysis.de.GermanLightStemFilterFactory,
+ org.apache.lucene.analysis.de.GermanMinimalStemFilterFactory,
+ org.apache.lucene.analysis.de.GermanNormalizationFilterFactory,
+ org.apache.lucene.analysis.de.GermanStemFilterFactory,
+ org.apache.lucene.analysis.el.GreekLowerCaseFilterFactory,
+ org.apache.lucene.analysis.el.GreekStemFilterFactory,
+ org.apache.lucene.analysis.en.EnglishMinimalStemFilterFactory,
+ org.apache.lucene.analysis.en.EnglishPossessiveFilterFactory,
+ org.apache.lucene.analysis.en.KStemFilterFactory,
+ org.apache.lucene.analysis.en.PorterStemFilterFactory,
+ org.apache.lucene.analysis.es.SpanishLightStemFilterFactory,
+ org.apache.lucene.analysis.es.SpanishMinimalStemFilterFactory,
+ org.apache.lucene.analysis.es.SpanishPluralStemFilterFactory,
+ org.apache.lucene.analysis.fa.PersianNormalizationFilterFactory,
+ org.apache.lucene.analysis.fi.FinnishLightStemFilterFactory,
+ org.apache.lucene.analysis.fr.FrenchLightStemFilterFactory,
+ org.apache.lucene.analysis.fr.FrenchMinimalStemFilterFactory,
+ org.apache.lucene.analysis.ga.IrishLowerCaseFilterFactory,
+ org.apache.lucene.analysis.gl.GalicianMinimalStemFilterFactory,
+ org.apache.lucene.analysis.gl.GalicianStemFilterFactory,
+ org.apache.lucene.analysis.hi.HindiNormalizationFilterFactory,
+ org.apache.lucene.analysis.hi.HindiStemFilterFactory,
+ org.apache.lucene.analysis.hu.HungarianLightStemFilterFactory,
+ org.apache.lucene.analysis.hunspell.HunspellStemFilterFactory,
+ org.apache.lucene.analysis.id.IndonesianStemFilterFactory,
+ org.apache.lucene.analysis.in.IndicNormalizationFilterFactory,
+ org.apache.lucene.analysis.it.ItalianLightStemFilterFactory,
+ org.apache.lucene.analysis.lv.LatvianStemFilterFactory,
+ org.apache.lucene.analysis.minhash.MinHashFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.CapitalizationFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.CodepointCountFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.ConcatenateGraphFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.DateRecognizerFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.DelimitedTermFrequencyTokenFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.DropIfFlaggedFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.FingerprintFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.FixBrokenOffsetsFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.HyphenatedWordsFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.KeepWordFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.KeywordMarkerFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.KeywordRepeatFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.LengthFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.LimitTokenCountFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.LimitTokenOffsetFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.LimitTokenPositionFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.RemoveDuplicatesTokenFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.StemmerOverrideFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.ProtectedTermFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.TrimFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.TruncateTokenFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.TypeAsSynonymFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.WordDelimiterFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.WordDelimiterGraphFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.ScandinavianFoldingFilterFactory,
+ org.apache.lucene.analysis.miscellaneous.ScandinavianNormalizationFilterFactory,
+ org.apache.lucene.analysis.ngram.EdgeNGramFilterFactory,
+ org.apache.lucene.analysis.ngram.NGramFilterFactory,
+ org.apache.lucene.analysis.no.NorwegianLightStemFilterFactory,
+ org.apache.lucene.analysis.no.NorwegianMinimalStemFilterFactory,
+ org.apache.lucene.analysis.no.NorwegianNormalizationFilterFactory,
+ org.apache.lucene.analysis.pattern.PatternReplaceFilterFactory,
+ org.apache.lucene.analysis.pattern.PatternCaptureGroupFilterFactory,
+ org.apache.lucene.analysis.pattern.PatternTypingFilterFactory,
+ org.apache.lucene.analysis.payloads.DelimitedPayloadTokenFilterFactory,
+ org.apache.lucene.analysis.payloads.NumericPayloadTokenFilterFactory,
+ org.apache.lucene.analysis.payloads.TokenOffsetPayloadTokenFilterFactory,
+ org.apache.lucene.analysis.payloads.TypeAsPayloadTokenFilterFactory,
+ org.apache.lucene.analysis.pt.PortugueseLightStemFilterFactory,
+ org.apache.lucene.analysis.pt.PortugueseMinimalStemFilterFactory,
+ org.apache.lucene.analysis.pt.PortugueseStemFilterFactory,
+ org.apache.lucene.analysis.reverse.ReverseStringFilterFactory,
+ org.apache.lucene.analysis.ru.RussianLightStemFilterFactory,
+ org.apache.lucene.analysis.shingle.ShingleFilterFactory,
+ org.apache.lucene.analysis.shingle.FixedShingleFilterFactory,
+ org.apache.lucene.analysis.snowball.SnowballPorterFilterFactory,
+ org.apache.lucene.analysis.sr.SerbianNormalizationFilterFactory,
+ org.apache.lucene.analysis.sv.SwedishLightStemFilterFactory,
+ org.apache.lucene.analysis.sv.SwedishMinimalStemFilterFactory,
+ org.apache.lucene.analysis.synonym.SynonymFilterFactory,
+ org.apache.lucene.analysis.synonym.SynonymGraphFilterFactory,
+ org.apache.lucene.analysis.core.FlattenGraphFilterFactory,
+ org.apache.lucene.analysis.te.TeluguNormalizationFilterFactory,
+ org.apache.lucene.analysis.te.TeluguStemFilterFactory,
+ org.apache.lucene.analysis.tr.TurkishLowerCaseFilterFactory,
+ org.apache.lucene.analysis.util.ElisionFilterFactory;
+ provides org.apache.lucene.analysis.TokenizerFactory with
+ org.apache.lucene.analysis.classic.ClassicTokenizerFactory,
+ org.apache.lucene.analysis.core.KeywordTokenizerFactory,
+ org.apache.lucene.analysis.core.LetterTokenizerFactory,
+ org.apache.lucene.analysis.core.WhitespaceTokenizerFactory,
+ org.apache.lucene.analysis.email.UAX29URLEmailTokenizerFactory,
+ org.apache.lucene.analysis.ngram.EdgeNGramTokenizerFactory,
+ org.apache.lucene.analysis.ngram.NGramTokenizerFactory,
+ org.apache.lucene.analysis.path.PathHierarchyTokenizerFactory,
+ org.apache.lucene.analysis.pattern.PatternTokenizerFactory,
+ org.apache.lucene.analysis.pattern.SimplePatternSplitTokenizerFactory,
+ org.apache.lucene.analysis.pattern.SimplePatternTokenizerFactory,
+ org.apache.lucene.analysis.th.ThaiTokenizerFactory,
+ org.apache.lucene.analysis.wikipedia.WikipediaTokenizerFactory;
+}
diff --git a/lucene/analysis/icu/build.gradle b/lucene/analysis/icu/build.gradle
index 2eab963..e76b327 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/analysis/icu/build.gradle
@@ -20,10 +20,10 @@ apply plugin: 'java-library'
description = 'Analysis integration with ICU (International Components for Unicode)'
dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
+ moduleApi project(':lucene:core')
+ moduleApi project(':lucene:analysis:common')
- api 'com.ibm.icu:icu4j'
+ moduleApi 'com.ibm.icu:icu4j'
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/analysis/icu/src/java/module-info.java b/lucene/analysis/icu/src/java/module-info.java
new file mode 100644
index 0000000..c901af4
--- /dev/null
+++ b/lucene/analysis/icu/src/java/module-info.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+/** Analysis integration with ICU */
+@SuppressWarnings({"requires-automatic"})
+module org.apache.lucene.analysis.icu {
+ requires com.ibm.icu;
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
+
+ exports org.apache.lucene.analysis.icu;
+ exports org.apache.lucene.analysis.icu.segmentation;
+ exports org.apache.lucene.analysis.icu.tokenattributes;
+
+ provides org.apache.lucene.analysis.CharFilterFactory with
+ org.apache.lucene.analysis.icu.ICUNormalizer2CharFilterFactory;
+ provides org.apache.lucene.analysis.TokenizerFactory with
+ org.apache.lucene.analysis.icu.segmentation.ICUTokenizerFactory;
+ provides org.apache.lucene.analysis.TokenFilterFactory with
+ org.apache.lucene.analysis.icu.ICUFoldingFilterFactory,
+ org.apache.lucene.analysis.icu.ICUNormalizer2FilterFactory,
+ org.apache.lucene.analysis.icu.ICUTransformFilterFactory;
+}
diff --git a/lucene/analysis/kuromoji/build.gradle b/lucene/analysis/kuromoji/build.gradle
index af2bfa5..07fc0b0 100644
--- a/lucene/analysis/kuromoji/build.gradle
+++ b/lucene/analysis/kuromoji/build.gradle
@@ -20,8 +20,8 @@ apply plugin: 'java-library'
description = 'Japanese Morphological Analyzer'
dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
+ moduleApi project(':lucene:core')
+ moduleApi project(':lucene:analysis:common')
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/analysis/kuromoji/src/java/module-info.java b/lucene/analysis/kuromoji/src/java/module-info.java
new file mode 100644
index 0000000..7c829fd
--- /dev/null
+++ b/lucene/analysis/kuromoji/src/java/module-info.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** Japanese Morphological Analyzer */
+module org.apache.lucene.analysis.kuromoji {
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
+
+ exports org.apache.lucene.analysis.ja;
+ exports org.apache.lucene.analysis.ja.completion;
+ exports org.apache.lucene.analysis.ja.dict;
+ exports org.apache.lucene.analysis.ja.tokenattributes;
+ exports org.apache.lucene.analysis.ja.util;
+
+ provides org.apache.lucene.analysis.CharFilterFactory with
+ org.apache.lucene.analysis.ja.JapaneseIterationMarkCharFilterFactory;
+ provides org.apache.lucene.analysis.TokenizerFactory with
+ org.apache.lucene.analysis.ja.JapaneseTokenizerFactory;
+ provides org.apache.lucene.analysis.TokenFilterFactory with
+ org.apache.lucene.analysis.ja.JapaneseBaseFormFilterFactory,
+ org.apache.lucene.analysis.ja.JapaneseCompletionFilterFactory,
+ org.apache.lucene.analysis.ja.JapaneseKatakanaStemFilterFactory,
+ org.apache.lucene.analysis.ja.JapaneseNumberFilterFactory,
+ org.apache.lucene.analysis.ja.JapanesePartOfSpeechStopFilterFactory,
+ org.apache.lucene.analysis.ja.JapaneseReadingFormFilterFactory;
+}
diff --git a/lucene/analysis/kuromoji/build.gradle b/lucene/analysis/morfologik.tests/build.gradle
similarity index 76%
copy from lucene/analysis/kuromoji/build.gradle
copy to lucene/analysis/morfologik.tests/build.gradle
index af2bfa5..9cd6720 100644
--- a/lucene/analysis/kuromoji/build.gradle
+++ b/lucene/analysis/morfologik.tests/build.gradle
@@ -17,11 +17,12 @@
apply plugin: 'java-library'
-description = 'Japanese Morphological Analyzer'
+description = 'Module tests for :lucene:analysis:morfologik'
dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- testImplementation project(':lucene:test-framework')
+ moduleTestImplementation project(':lucene:analysis:morfologik')
+ moduleTestImplementation("junit:junit", {
+ exclude group: "org.hamcrest"
+ })
+ moduleTestImplementation "org.hamcrest:hamcrest"
}
diff --git a/lucene/analysis/icu/build.gradle b/lucene/analysis/morfologik.tests/src/test/module-info.java
similarity index 68%
copy from lucene/analysis/icu/build.gradle
copy to lucene/analysis/morfologik.tests/src/test/module-info.java
index 2eab963..15642a9 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/analysis/morfologik.tests/src/test/module-info.java
@@ -15,15 +15,13 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Test module for {@code org.apache.lucene.analysis.morfologik}. */
+@SuppressWarnings({"requires-automatic"})
+module org.apache.lucene.analysis.morfologik.tests {
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
+ requires org.apache.lucene.analysis.morfologik;
+ requires junit;
-description = 'Analysis integration with ICU (International Components for Unicode)'
-
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'com.ibm.icu:icu4j'
-
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.analysis.morfologik.tests;
}
diff --git a/lucene/analysis/morfologik.tests/src/test/org/apache/lucene/analysis/morfologik/tests/TestMorfologikAnalyzer.java b/lucene/analysis/morfologik.tests/src/test/org/apache/lucene/analysis/morfologik/tests/TestMorfologikAnalyzer.java
new file mode 100644
index 0000000..c2933fc
--- /dev/null
+++ b/lucene/analysis/morfologik.tests/src/test/org/apache/lucene/analysis/morfologik/tests/TestMorfologikAnalyzer.java
@@ -0,0 +1,47 @@
+/*
+ * 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.analysis.morfologik.tests;
+
+import org.apache.lucene.analysis.morfologik.MorfologikAnalyzer;
+import org.apache.lucene.analysis.uk.UkrainianMorfologikAnalyzer;
+import org.apache.lucene.index.IndexWriter;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestMorfologikAnalyzer {
+ @Test
+ public void testMorfologikAnalyzerLoads() {
+ var analyzer = new MorfologikAnalyzer();
+ Assert.assertNotNull(analyzer);
+ }
+
+ @Test
+ public void testUkrainianMorfologikAnalyzerLoads() {
+ var analyzer = new UkrainianMorfologikAnalyzer();
+ Assert.assertNotNull(analyzer);
+ }
+
+ @Test
+ public void testWeAreModule() {
+ Assert.assertTrue(this.getClass().getModule().isNamed());
+ }
+
+ @Test
+ public void testLuceneIsAModule() {
+ Assert.assertTrue(IndexWriter.class.getModule().isNamed());
+ }
+}
diff --git a/lucene/analysis/morfologik/build.gradle b/lucene/analysis/morfologik/build.gradle
index 153515f..03d7c09 100644
--- a/lucene/analysis/morfologik/build.gradle
+++ b/lucene/analysis/morfologik/build.gradle
@@ -20,13 +20,12 @@ apply plugin: 'java-library'
description = 'Analyzer for dictionary stemming, built-in Polish dictionary'
dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
+ moduleApi project(':lucene:core')
+ moduleApi project(':lucene:analysis:common')
+ moduleApi 'org.carrot2:morfologik-stemming'
- api 'org.carrot2:morfologik-stemming'
-
- implementation 'org.carrot2:morfologik-polish'
- implementation 'ua.net.nlp:morfologik-ukrainian-search'
+ moduleImplementation 'org.carrot2:morfologik-polish'
+ moduleImplementation 'ua.net.nlp:morfologik-ukrainian-search'
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/analysis/morfologik/build.gradle b/lucene/analysis/morfologik/src/java/module-info.java
similarity index 57%
copy from lucene/analysis/morfologik/build.gradle
copy to lucene/analysis/morfologik/src/java/module-info.java
index 153515f..3268d4b 100644
--- a/lucene/analysis/morfologik/build.gradle
+++ b/lucene/analysis/morfologik/src/java/module-info.java
@@ -15,18 +15,18 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Analyzer for dictionary stemming, built-in Polish dictionary */
+@SuppressWarnings({"requires-automatic"})
+module org.apache.lucene.analysis.morfologik {
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
+ requires org.carrot2.morfologik.stemming;
+ requires org.carrot2.morfologik.polish;
+ requires morfologik.ukrainian.search;
-description = 'Analyzer for dictionary stemming, built-in Polish dictionary'
+ exports org.apache.lucene.analysis.morfologik;
+ exports org.apache.lucene.analysis.uk;
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'org.carrot2:morfologik-stemming'
-
- implementation 'org.carrot2:morfologik-polish'
- implementation 'ua.net.nlp:morfologik-ukrainian-search'
-
- testImplementation project(':lucene:test-framework')
+ provides org.apache.lucene.analysis.TokenFilterFactory with
+ org.apache.lucene.analysis.morfologik.MorfologikFilterFactory;
}
diff --git a/lucene/analysis/morfologik/src/java/org/apache/lucene/analysis/uk/UkrainianMorfologikAnalyzer.java b/lucene/analysis/morfologik/src/java/org/apache/lucene/analysis/uk/UkrainianMorfologikAnalyzer.java
index 425a55c6..b80ccb6 100644
--- a/lucene/analysis/morfologik/src/java/org/apache/lucene/analysis/uk/UkrainianMorfologikAnalyzer.java
+++ b/lucene/analysis/morfologik/src/java/org/apache/lucene/analysis/uk/UkrainianMorfologikAnalyzer.java
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.io.Reader;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
+import java.util.Objects;
import morfologik.stemming.Dictionary;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.CharArraySet;
@@ -42,12 +43,9 @@ import org.apache.lucene.util.IOUtils;
* @since 6.2.0
*/
public final class UkrainianMorfologikAnalyzer extends StopwordAnalyzerBase {
-
+ private final Dictionary dictionary;
private final CharArraySet stemExclusionSet;
- /** File containing default Ukrainian stopwords. */
- public static final String DEFAULT_STOPWORD_FILE = "stopwords.txt";
-
private static final NormalizeCharMap NORMALIZER_MAP;
static {
@@ -67,47 +65,72 @@ public final class UkrainianMorfologikAnalyzer extends StopwordAnalyzerBase {
NORMALIZER_MAP = builder.build();
}
- /**
- * Returns an unmodifiable instance of the default stop words set.
- *
- * @return default stop words set.
- */
- public static CharArraySet getDefaultStopSet() {
- return DefaultSetHolder.DEFAULT_STOP_SET;
+ /** Returns a lazy singleton with the default Ukrainian resources. */
+ private static volatile DefaultResources defaultResources;
+
+ private static DefaultResources getDefaultResources() {
+ if (defaultResources == null) {
+ synchronized (DefaultResources.class) {
+ try {
+ CharArraySet wordList;
+ try (var is = UkrainianMorfologikAnalyzer.class.getResourceAsStream("stopwords.txt")) {
+ if (is == null) {
+ throw new IOException("Could not locate the required stopwords resource.");
+ }
+ wordList =
+ WordlistLoader.getSnowballWordSet(
+ IOUtils.getDecodingReader(is, StandardCharsets.UTF_8));
+ }
+
+ // First, try to look up the resource module by name.
+ Dictionary dictionary;
+ Module ourModule = DefaultResources.class.getModule();
+ if (ourModule.isNamed() && ourModule.getLayer() != null) {
+ var module =
+ ourModule
+ .getLayer()
+ .findModule("morfologik.ukrainian.search")
+ .orElseThrow(
+ () ->
+ new IOException(
+ "Can't find the resource module: morfologik.ukrainian.search"));
+
+ try (var fsaStream = module.getResourceAsStream("ua/net/nlp/ukrainian.dict");
+ var metaStream = module.getResourceAsStream("ua/net/nlp/ukrainian.info")) {
+ dictionary = Dictionary.read(fsaStream, metaStream);
+ }
+ } else {
+ dictionary =
+ Dictionary.read(
+ Objects.requireNonNull(
+ UkrainianMorfologikAnalyzer.class
+ .getClassLoader()
+ .getResource("ua/net/nlp/ukrainian.dict"),
+ "Could not locate the required Ukrainian dictionary resource."));
+ }
+ defaultResources = new DefaultResources(wordList, dictionary);
+ } catch (IOException e) {
+ throw new UncheckedIOException(
+ "Could not load the required resources for the Ukrainian analyzer.", e);
+ }
+ }
+ }
+ return defaultResources;
}
- /**
- * Atomically loads the DEFAULT_STOP_SET and DICTIONARY in a lazy fashion once the outer class
- * accesses the static final set the first time.;
- */
- private static class DefaultSetHolder {
- static final CharArraySet DEFAULT_STOP_SET;
- static final Dictionary DICTIONARY;
-
- static {
- try {
- DEFAULT_STOP_SET =
- WordlistLoader.getSnowballWordSet(
- IOUtils.getDecodingReader(
- UkrainianMorfologikAnalyzer.class,
- DEFAULT_STOPWORD_FILE,
- StandardCharsets.UTF_8));
- DICTIONARY =
- Dictionary.read(
- UkrainianMorfologikAnalyzer.class
- .getClassLoader()
- .getResource("ua/net/nlp/ukrainian.dict"));
- } catch (IOException ex) {
- // default set should always be present as it is part of the
- // distribution (JAR)
- throw new UncheckedIOException("Unable to load analyzer resources", ex);
- }
+ private static class DefaultResources {
+ final CharArraySet stopSet;
+ final Dictionary dictionary;
+
+ private DefaultResources(CharArraySet stopSet, Dictionary dictionary) {
+ this.stopSet = stopSet;
+ this.dictionary = dictionary;
}
}
- /** Builds an analyzer with the default stop words: {@link #DEFAULT_STOPWORD_FILE}. */
+ /** Builds an analyzer with the default stop words. */
public UkrainianMorfologikAnalyzer() {
- this(DefaultSetHolder.DEFAULT_STOP_SET);
+ this(getDefaultResources().stopSet);
}
/**
@@ -129,6 +152,7 @@ public final class UkrainianMorfologikAnalyzer extends StopwordAnalyzerBase {
public UkrainianMorfologikAnalyzer(CharArraySet stopwords, CharArraySet stemExclusionSet) {
super(stopwords);
this.stemExclusionSet = CharArraySet.unmodifiableSet(CharArraySet.copy(stemExclusionSet));
+ this.dictionary = getDefaultResources().dictionary;
}
@Override
@@ -155,7 +179,7 @@ public final class UkrainianMorfologikAnalyzer extends StopwordAnalyzerBase {
result = new SetKeywordMarkerFilter(result, stemExclusionSet);
}
- result = new MorfologikFilter(result, DefaultSetHolder.DICTIONARY);
+ result = new MorfologikFilter(result, dictionary);
return new TokenStreamComponents(source, result);
}
}
diff --git a/lucene/analysis/nori/build.gradle b/lucene/analysis/nori/build.gradle
index 430673c..079cf50 100644
--- a/lucene/analysis/nori/build.gradle
+++ b/lucene/analysis/nori/build.gradle
@@ -20,8 +20,8 @@ apply plugin: 'java-library'
description = 'Korean Morphological Analyzer'
dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
+ moduleApi project(':lucene:core')
+ moduleApi project(':lucene:analysis:common')
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/analysis/icu/build.gradle b/lucene/analysis/nori/src/java/module-info.java
similarity index 54%
copy from lucene/analysis/icu/build.gradle
copy to lucene/analysis/nori/src/java/module-info.java
index 2eab963..9dd085b 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/analysis/nori/src/java/module-info.java
@@ -15,15 +15,19 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Korean Morphological Analyzer */
+module org.apache.lucene.analysis.nori {
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
-description = 'Analysis integration with ICU (International Components for Unicode)'
+ exports org.apache.lucene.analysis.ko;
+ exports org.apache.lucene.analysis.ko.dict;
+ exports org.apache.lucene.analysis.ko.tokenattributes;
+ exports org.apache.lucene.analysis.ko.util;
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'com.ibm.icu:icu4j'
-
- testImplementation project(':lucene:test-framework')
+ provides org.apache.lucene.analysis.TokenizerFactory with
+ org.apache.lucene.analysis.ko.KoreanTokenizerFactory;
+ provides org.apache.lucene.analysis.TokenFilterFactory with
+ org.apache.lucene.analysis.ko.KoreanPartOfSpeechStopFilterFactory,
+ org.apache.lucene.analysis.ko.KoreanReadingFormFilterFactory;
}
diff --git a/lucene/analysis/opennlp/build.gradle b/lucene/analysis/opennlp/build.gradle
index c4672c0..3fee61a 100644
--- a/lucene/analysis/opennlp/build.gradle
+++ b/lucene/analysis/opennlp/build.gradle
@@ -20,9 +20,9 @@ apply plugin: 'java-library'
description = 'OpenNLP Library Integration'
dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
- api 'org.apache.opennlp:opennlp-tools'
+ moduleApi project(':lucene:core')
+ moduleApi project(':lucene:analysis:common')
+ moduleApi 'org.apache.opennlp:opennlp-tools'
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/analysis/icu/build.gradle b/lucene/analysis/opennlp/src/java/module-info.java
similarity index 52%
copy from lucene/analysis/icu/build.gradle
copy to lucene/analysis/opennlp/src/java/module-info.java
index 2eab963..c63ecfa 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/analysis/opennlp/src/java/module-info.java
@@ -15,15 +15,20 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** OpenNLP Library Integration */
+@SuppressWarnings({"requires-automatic"})
+module org.apache.lucene.analysis.opennlp {
+ requires org.apache.opennlp.tools;
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
-description = 'Analysis integration with ICU (International Components for Unicode)'
+ exports org.apache.lucene.analysis.opennlp;
+ exports org.apache.lucene.analysis.opennlp.tools;
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'com.ibm.icu:icu4j'
-
- testImplementation project(':lucene:test-framework')
+ provides org.apache.lucene.analysis.TokenizerFactory with
+ org.apache.lucene.analysis.opennlp.OpenNLPTokenizerFactory;
+ provides org.apache.lucene.analysis.TokenFilterFactory with
+ org.apache.lucene.analysis.opennlp.OpenNLPChunkerFilterFactory,
+ org.apache.lucene.analysis.opennlp.OpenNLPLemmatizerFilterFactory,
+ org.apache.lucene.analysis.opennlp.OpenNLPPOSFilterFactory;
}
diff --git a/lucene/analysis/phonetic/build.gradle b/lucene/analysis/phonetic/build.gradle
index 0f716e8..e5595cb 100644
--- a/lucene/analysis/phonetic/build.gradle
+++ b/lucene/analysis/phonetic/build.gradle
@@ -20,10 +20,10 @@ apply plugin: 'java-library'
description = 'Analyzer for indexing phonetic signatures (for sounds-alike search)'
dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
+ moduleApi project(':lucene:core')
+ moduleApi project(':lucene:analysis:common')
- implementation 'commons-codec:commons-codec'
+ moduleImplementation 'commons-codec:commons-codec'
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/analysis/morfologik/build.gradle b/lucene/analysis/phonetic/src/java/module-info.java
similarity index 58%
copy from lucene/analysis/morfologik/build.gradle
copy to lucene/analysis/phonetic/src/java/module-info.java
index 153515f..706251a 100644
--- a/lucene/analysis/morfologik/build.gradle
+++ b/lucene/analysis/phonetic/src/java/module-info.java
@@ -15,18 +15,17 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Analyzer for indexing phonetic signatures */
+@SuppressWarnings({"requires-automatic"})
+module org.apache.lucene.analysis.phonetic {
+ requires org.apache.commons.codec;
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
-description = 'Analyzer for dictionary stemming, built-in Polish dictionary'
+ exports org.apache.lucene.analysis.phonetic;
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'org.carrot2:morfologik-stemming'
-
- implementation 'org.carrot2:morfologik-polish'
- implementation 'ua.net.nlp:morfologik-ukrainian-search'
-
- testImplementation project(':lucene:test-framework')
+ provides org.apache.lucene.analysis.TokenFilterFactory with
+ org.apache.lucene.analysis.phonetic.BeiderMorseFilterFactory,
+ org.apache.lucene.analysis.phonetic.DoubleMetaphoneFilterFactory,
+ org.apache.lucene.analysis.phonetic.PhoneticFilterFactory;
}
diff --git a/lucene/analysis/smartcn/build.gradle b/lucene/analysis/smartcn/build.gradle
index 8d5eeb1..960be70 100644
--- a/lucene/analysis/smartcn/build.gradle
+++ b/lucene/analysis/smartcn/build.gradle
@@ -20,8 +20,8 @@ apply plugin: 'java-library'
description = 'Analyzer for indexing Chinese'
dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
+ moduleApi project(':lucene:core')
+ moduleApi project(':lucene:analysis:common')
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/analysis/icu/build.gradle b/lucene/analysis/smartcn/src/java/module-info.java
similarity index 67%
copy from lucene/analysis/icu/build.gradle
copy to lucene/analysis/smartcn/src/java/module-info.java
index 2eab963..44f4eb5 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/analysis/smartcn/src/java/module-info.java
@@ -15,15 +15,14 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Analyzer for indexing Chinese */
+module org.apache.lucene.analysis.smartcn {
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
-description = 'Analysis integration with ICU (International Components for Unicode)'
+ exports org.apache.lucene.analysis.cn.smart;
+ exports org.apache.lucene.analysis.cn.smart.hhmm;
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'com.ibm.icu:icu4j'
-
- testImplementation project(':lucene:test-framework')
+ provides org.apache.lucene.analysis.TokenizerFactory with
+ org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory;
}
diff --git a/lucene/analysis/stempel/build.gradle b/lucene/analysis/stempel/build.gradle
index 3b80f9f..3299159 100644
--- a/lucene/analysis/stempel/build.gradle
+++ b/lucene/analysis/stempel/build.gradle
@@ -20,8 +20,8 @@ apply plugin: 'java-library'
description = 'Analyzer for indexing Polish'
dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
+ moduleApi project(':lucene:core')
+ moduleApi project(':lucene:analysis:common')
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/analysis/icu/build.gradle b/lucene/analysis/stempel/src/java/module-info.java
similarity index 66%
copy from lucene/analysis/icu/build.gradle
copy to lucene/analysis/stempel/src/java/module-info.java
index 2eab963..d559548 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/analysis/stempel/src/java/module-info.java
@@ -15,15 +15,15 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Analyzer for indexing Polish */
+module org.apache.lucene.analysis.stempel {
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
-description = 'Analysis integration with ICU (International Components for Unicode)'
+ exports org.apache.lucene.analysis.pl;
+ exports org.apache.lucene.analysis.stempel;
+ exports org.egothor.stemmer;
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'com.ibm.icu:icu4j'
-
- testImplementation project(':lucene:test-framework')
+ provides org.apache.lucene.analysis.TokenFilterFactory with
+ org.apache.lucene.analysis.stempel.StempelPolishStemFilterFactory;
}
diff --git a/lucene/backward-codecs/build.gradle b/lucene/backward-codecs/build.gradle
index aa47302..d5e25d9 100644
--- a/lucene/backward-codecs/build.gradle
+++ b/lucene/backward-codecs/build.gradle
@@ -20,7 +20,7 @@ apply plugin: 'java-library'
description = 'Codecs for older versions of Lucene'
-dependencies {
- api project(':lucene:core')
+dependencies {
+ moduleApi project(':lucene:core')
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/backward-codecs/src/java/module-info.java b/lucene/backward-codecs/src/java/module-info.java
new file mode 100644
index 0000000..8e01546
--- /dev/null
+++ b/lucene/backward-codecs/src/java/module-info.java
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/** Codecs for older versions of Lucene */
+module org.apache.lucene.backward_codecs {
+ requires org.apache.lucene.core;
+
+ exports org.apache.lucene.backward_codecs;
+ exports org.apache.lucene.backward_codecs.lucene40.blocktree;
+ exports org.apache.lucene.backward_codecs.lucene50;
+ exports org.apache.lucene.backward_codecs.lucene50.compressing;
+ exports org.apache.lucene.backward_codecs.lucene60;
+ exports org.apache.lucene.backward_codecs.lucene70;
+ exports org.apache.lucene.backward_codecs.lucene80;
+ exports org.apache.lucene.backward_codecs.lucene84;
+ exports org.apache.lucene.backward_codecs.lucene86;
+ exports org.apache.lucene.backward_codecs.lucene87;
+ exports org.apache.lucene.backward_codecs.packed;
+ exports org.apache.lucene.backward_codecs.store;
+
+ provides org.apache.lucene.codecs.DocValuesFormat with
+ org.apache.lucene.backward_codecs.lucene70.Lucene70DocValuesFormat,
+ org.apache.lucene.backward_codecs.lucene80.Lucene80DocValuesFormat;
+ provides org.apache.lucene.codecs.PostingsFormat with
+ org.apache.lucene.backward_codecs.lucene50.Lucene50PostingsFormat,
+ org.apache.lucene.backward_codecs.lucene84.Lucene84PostingsFormat;
+ provides org.apache.lucene.codecs.Codec with
+ org.apache.lucene.backward_codecs.lucene70.Lucene70Codec,
+ org.apache.lucene.backward_codecs.lucene80.Lucene80Codec,
+ org.apache.lucene.backward_codecs.lucene84.Lucene84Codec,
+ org.apache.lucene.backward_codecs.lucene86.Lucene86Codec,
+ org.apache.lucene.backward_codecs.lucene87.Lucene87Codec;
+}
diff --git a/lucene/benchmark/build.gradle b/lucene/benchmark/build.gradle
index 67b1644..9da51c3 100644
--- a/lucene/benchmark/build.gradle
+++ b/lucene/benchmark/build.gradle
@@ -22,23 +22,23 @@ plugins {
description = 'Lucene benchmarking module'
dependencies {
- implementation project(':lucene:core')
+ moduleImplementation project(':lucene:core')
- implementation project(':lucene:analysis:common')
- implementation project(':lucene:facet')
- implementation project(':lucene:highlighter')
- implementation project(':lucene:queries')
- implementation project(':lucene:spatial-extras')
- implementation project(':lucene:queryparser')
+ moduleImplementation project(':lucene:analysis:common')
+ moduleImplementation project(':lucene:facet')
+ moduleImplementation project(':lucene:highlighter')
+ moduleImplementation project(':lucene:queries')
+ moduleImplementation project(':lucene:spatial-extras')
+ moduleImplementation project(':lucene:queryparser')
- implementation "org.apache.commons:commons-compress"
- implementation "com.ibm.icu:icu4j"
- implementation "org.locationtech.spatial4j:spatial4j"
- implementation("net.sourceforge.nekohtml:nekohtml", {
+ moduleImplementation "org.apache.commons:commons-compress"
+ moduleImplementation "com.ibm.icu:icu4j"
+ moduleImplementation "org.locationtech.spatial4j:spatial4j"
+ moduleImplementation ("net.sourceforge.nekohtml:nekohtml", {
exclude module: "xml-apis"
})
- runtimeOnly project(':lucene:analysis:icu')
+ moduleRuntimeOnly project(':lucene:analysis:icu')
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/benchmark/src/java/module-info.java b/lucene/benchmark/src/java/module-info.java
new file mode 100644
index 0000000..f3dfac9
--- /dev/null
+++ b/lucene/benchmark/src/java/module-info.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@SuppressWarnings({"requires-automatic"})
+module org.apache.lucene.benchmark {
+ requires java.xml;
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
+ requires org.apache.lucene.facet;
+ requires org.apache.lucene.highlighter;
+ requires org.apache.lucene.queries;
+ requires org.apache.lucene.queryparser;
+ requires org.apache.lucene.spatial_extras;
+ requires spatial4j;
+
+ exports org.apache.lucene.benchmark;
+ exports org.apache.lucene.benchmark.byTask;
+ exports org.apache.lucene.benchmark.byTask.feeds;
+ exports org.apache.lucene.benchmark.byTask.programmatic;
+ exports org.apache.lucene.benchmark.byTask.stats;
+ exports org.apache.lucene.benchmark.byTask.tasks;
+ exports org.apache.lucene.benchmark.byTask.utils;
+ exports org.apache.lucene.benchmark.quality;
+ exports org.apache.lucene.benchmark.quality.trec;
+ exports org.apache.lucene.benchmark.quality.utils;
+ exports org.apache.lucene.benchmark.utils;
+}
diff --git a/lucene/classification/build.gradle b/lucene/classification/build.gradle
index 736dfb3..8566cdb 100644
--- a/lucene/classification/build.gradle
+++ b/lucene/classification/build.gradle
@@ -20,10 +20,10 @@ apply plugin: 'java-library'
description = 'Classification module for Lucene'
dependencies {
- api project(':lucene:core')
+ moduleApi project(':lucene:core')
- implementation project(':lucene:queries')
- implementation project(':lucene:grouping')
+ moduleImplementation project(':lucene:queries')
+ moduleImplementation project(':lucene:grouping')
testImplementation project(':lucene:test-framework')
testImplementation project(':lucene:analysis:common')
diff --git a/lucene/analysis/icu/build.gradle b/lucene/classification/src/java/module-info.java
similarity index 70%
copy from lucene/analysis/icu/build.gradle
copy to lucene/classification/src/java/module-info.java
index 2eab963..4817d8a 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/classification/src/java/module-info.java
@@ -15,15 +15,13 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Classification module for Lucene */
+module org.apache.lucene.classification {
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.queries;
+ requires org.apache.lucene.grouping;
-description = 'Analysis integration with ICU (International Components for Unicode)'
-
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'com.ibm.icu:icu4j'
-
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.classification;
+ exports org.apache.lucene.classification.document;
+ exports org.apache.lucene.classification.utils;
}
diff --git a/lucene/codecs/build.gradle b/lucene/codecs/build.gradle
index ad26aae..92e0782 100644
--- a/lucene/codecs/build.gradle
+++ b/lucene/codecs/build.gradle
@@ -20,6 +20,6 @@ apply plugin: 'java-library'
description = 'Lucene codecs and postings formats'
dependencies {
- implementation project(':lucene:core')
+ moduleImplementation project(':lucene:core')
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/codecs/src/java/module-info.java b/lucene/codecs/src/java/module-info.java
new file mode 100644
index 0000000..73f53fb
--- /dev/null
+++ b/lucene/codecs/src/java/module-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 codecs and postings formats */
+module org.apache.lucene.codecs {
+ requires org.apache.lucene.core;
+
+ exports org.apache.lucene.codecs.blockterms;
+ exports org.apache.lucene.codecs.blocktreeords;
+ exports org.apache.lucene.codecs.bloom;
+ exports org.apache.lucene.codecs.memory;
+ exports org.apache.lucene.codecs.simpletext;
+ exports org.apache.lucene.codecs.uniformsplit;
+ exports org.apache.lucene.codecs.uniformsplit.sharedterms;
+
+ provides org.apache.lucene.codecs.PostingsFormat with
+ org.apache.lucene.codecs.blocktreeords.BlockTreeOrdsPostingsFormat,
+ org.apache.lucene.codecs.bloom.BloomFilteringPostingsFormat,
+ org.apache.lucene.codecs.memory.DirectPostingsFormat,
+ org.apache.lucene.codecs.memory.FSTPostingsFormat,
+ org.apache.lucene.codecs.uniformsplit.UniformSplitPostingsFormat,
+ org.apache.lucene.codecs.uniformsplit.sharedterms.STUniformSplitPostingsFormat;
+ provides org.apache.lucene.codecs.Codec with
+ org.apache.lucene.codecs.simpletext.SimpleTextCodec;
+}
diff --git a/lucene/core/src/java/module-info.java b/lucene/core/src/java/module-info.java
new file mode 100644
index 0000000..931d4cb
--- /dev/null
+++ b/lucene/core/src/java/module-info.java
@@ -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.
+ */
+
+/** Lucene Core. */
+module org.apache.lucene.core {
+ requires jdk.unsupported; // this is needed for MMapDirectory to unmap
+
+ exports org.apache.lucene.analysis;
+ exports org.apache.lucene.analysis.standard;
+ exports org.apache.lucene.analysis.tokenattributes;
+ exports org.apache.lucene.codecs;
+ exports org.apache.lucene.codecs.compressing;
+ exports org.apache.lucene.codecs.lucene90;
+ exports org.apache.lucene.codecs.lucene90.blocktree;
+ exports org.apache.lucene.codecs.lucene90.compressing;
+ exports org.apache.lucene.codecs.perfield;
+ exports org.apache.lucene.document;
+ exports org.apache.lucene.geo;
+ exports org.apache.lucene.index;
+ exports org.apache.lucene.search;
+ exports org.apache.lucene.search.comparators;
+ exports org.apache.lucene.search.similarities;
+ exports org.apache.lucene.store;
+ exports org.apache.lucene.util;
+ exports org.apache.lucene.util.automaton;
+ exports org.apache.lucene.util.bkd;
+ exports org.apache.lucene.util.compress;
+ exports org.apache.lucene.util.fst;
+ exports org.apache.lucene.util.graph;
+ exports org.apache.lucene.util.hnsw;
+ exports org.apache.lucene.util.hppc;
+ exports org.apache.lucene.util.mutable;
+ exports org.apache.lucene.util.packed;
+
+ provides org.apache.lucene.analysis.TokenizerFactory with
+ org.apache.lucene.analysis.standard.StandardTokenizerFactory;
+ provides org.apache.lucene.codecs.Codec with
+ org.apache.lucene.codecs.lucene90.Lucene90Codec;
+ provides org.apache.lucene.codecs.DocValuesFormat with
+ org.apache.lucene.codecs.lucene90.Lucene90DocValuesFormat;
+ provides org.apache.lucene.codecs.KnnVectorsFormat with
+ org.apache.lucene.codecs.lucene90.Lucene90HnswVectorsFormat;
+ provides org.apache.lucene.codecs.PostingsFormat with
+ org.apache.lucene.codecs.lucene90.Lucene90PostingsFormat;
+ provides org.apache.lucene.index.SortFieldProvider with
+ org.apache.lucene.search.SortField.Provider,
+ org.apache.lucene.search.SortedNumericSortField.Provider,
+ org.apache.lucene.search.SortedSetSortField.Provider;
+
+ uses org.apache.lucene.analysis.CharFilterFactory;
+ uses org.apache.lucene.analysis.TokenFilterFactory;
+ uses org.apache.lucene.analysis.TokenizerFactory;
+ uses org.apache.lucene.codecs.Codec;
+ uses org.apache.lucene.codecs.DocValuesFormat;
+ uses org.apache.lucene.codecs.KnnVectorsFormat;
+ uses org.apache.lucene.codecs.PostingsFormat;
+ uses org.apache.lucene.index.SortFieldProvider;
+}
diff --git a/lucene/demo/build.gradle b/lucene/demo/build.gradle
index 3624328..70fd1df 100644
--- a/lucene/demo/build.gradle
+++ b/lucene/demo/build.gradle
@@ -20,12 +20,12 @@ apply plugin: 'java-library'
description = 'Simple example code for Apache Lucene'
dependencies {
- implementation project(':lucene:core')
- implementation project(':lucene:facet')
- implementation project(':lucene:queries')
- implementation project(':lucene:analysis:common')
- implementation project(':lucene:queryparser')
- implementation project(':lucene:expressions')
+ moduleImplementation project(':lucene:core')
+ moduleImplementation project(':lucene:facet')
+ moduleImplementation project(':lucene:queries')
+ moduleImplementation project(':lucene:analysis:common')
+ moduleImplementation project(':lucene:queryparser')
+ moduleImplementation project(':lucene:expressions')
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/analysis/morfologik/build.gradle b/lucene/demo/src/java/module-info.java
similarity index 65%
copy from lucene/analysis/morfologik/build.gradle
copy to lucene/demo/src/java/module-info.java
index 153515f..13549a5 100644
--- a/lucene/analysis/morfologik/build.gradle
+++ b/lucene/demo/src/java/module-info.java
@@ -15,18 +15,16 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Simple example code for Apache Lucene */
+module org.apache.lucene.demo {
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
+ requires org.apache.lucene.facet;
+ requires org.apache.lucene.queries;
+ requires org.apache.lucene.queryparser;
+ requires org.apache.lucene.expressions;
-description = 'Analyzer for dictionary stemming, built-in Polish dictionary'
-
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'org.carrot2:morfologik-stemming'
-
- implementation 'org.carrot2:morfologik-polish'
- implementation 'ua.net.nlp:morfologik-ukrainian-search'
-
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.demo;
+ exports org.apache.lucene.demo.facet;
+ exports org.apache.lucene.demo.knn;
}
diff --git a/lucene/distribution.tests/build.gradle b/lucene/distribution.tests/build.gradle
new file mode 100644
index 0000000..30c4ae1
--- /dev/null
+++ b/lucene/distribution.tests/build.gradle
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+plugins {
+ id 'java-library'
+}
+
+configurations {
+ // This is a configuration that references an 'folder-expanded' binary distribution
+ // tests will run against. The distribution is slightly trimmed (no docs, licenses)
+ // because we don't test these parts of the distribution anyway.
+ binaryDistribution
+}
+
+dependencies {
+ binaryDistribution project(path: ":lucene:distribution", configuration: "binaryDirForTests")
+
+ moduleTestImplementation("com.carrotsearch.randomizedtesting:randomizedtesting-runner", {
+ exclude group: "junit"
+ })
+
+ moduleTestImplementation("junit:junit", {
+ exclude group: "org.hamcrest"
+ })
+ moduleTestImplementation "org.hamcrest:hamcrest"
+ moduleTestImplementation "org.assertj:assertj-core"
+}
+
+test {
+ dependsOn configurations.binaryDistribution
+
+ // We need to pass the system property using a lazy provider, not supported at the moment:
+ // https://github.com/gradle/gradle/issues/12247
+ // so we'll use a workaround and pass command-line arguments directly.
+ jvmArgumentProviders.add(new CommandLineArgumentProvider() {
+ @Override
+ Iterable<String> asArguments() {
+ return [
+ "-Dlucene.distribution.dir=${configurations.binaryDistribution.singleFile.absolutePath }",
+ "-Dlucene.distribution.version=${project.version}"
+ ]
+ }
+ })
+
+ doFirst {
+ logger.lifecycle("Testing binary distribution at: ${configurations.binaryDistribution.singleFile}")
+ }
+}
\ No newline at end of file
diff --git a/lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestModularLayer.java b/lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestModularLayer.java
new file mode 100644
index 0000000..5627089
--- /dev/null
+++ b/lucene/distribution.tests/src/test/org/apache/lucene/distribution/TestModularLayer.java
@@ -0,0 +1,295 @@
+/*
+ * 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.distribution;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReader;
+import java.lang.module.ModuleReference;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.assertj.core.api.Assertions;
+import org.assertj.core.api.Assumptions;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Sanity checks concerning the distribution's binary artifacts (modules).
+ *
+ * <p>We do <em>not</em> want this module to depend on any Lucene classes (including the test
+ * framework) so that there is no risk of accidental classpath space pollution. This also means the
+ * default {@code LuceneTestCase} configuration setup is not used (you have to annotate test for
+ * JUnit, for example).
+ */
+public class TestModularLayer {
+ /** A path to a directory with an expanded Lucene distribution. */
+ private static final String DISTRIBUTION_PROPERTY = "lucene.distribution.dir";
+
+ /** The expected distribution version of Lucene modules. */
+ private static final String VERSION_PROPERTY = "lucene.distribution.version";
+
+ /** Only core Lucene modules, no third party modules. */
+ private static Set<ModuleReference> allCoreModules;
+
+ /** {@link ModuleFinder} resolving only the Lucene modules. */
+ private static ModuleFinder coreModulesFinder;
+
+ /** Ensure Lucene classes are not directly visible. */
+ @BeforeClass
+ public static void checkLuceneNotInClasspath() {
+ Assertions.assertThatThrownBy(
+ () -> {
+ Class.forName("org.apache.lucene.index.IndexWriter");
+ })
+ .isInstanceOf(ClassNotFoundException.class);
+ }
+
+ /**
+ * We accept external properties that point to the assembled set of distribution modules and to
+ * their expected version. These properties are collected and passed by gradle but can be provided
+ * manually (for IDE launches).
+ */
+ @BeforeClass
+ public static void checkModulePathProvided() {
+ String modulesPropertyValue = System.getProperty(DISTRIBUTION_PROPERTY);
+ if (modulesPropertyValue == null) {
+ throw new AssertionError(DISTRIBUTION_PROPERTY + " property is required for this test.");
+ }
+
+ Path modulesPath = Paths.get(modulesPropertyValue).resolve("modules");
+ if (!Files.isDirectory(modulesPath)) {
+ throw new AssertionError(
+ DISTRIBUTION_PROPERTY
+ + " property does not point to a directory where this path is present: "
+ + modulesPath.toAbsolutePath());
+ }
+
+ Path thirdPartyModulesPath = Paths.get(modulesPropertyValue).resolve("modules-thirdparty");
+ if (!Files.isDirectory(thirdPartyModulesPath)) {
+ throw new AssertionError(
+ DISTRIBUTION_PROPERTY
+ + " property does not point to a directory where this path is present: "
+ + thirdPartyModulesPath.toAbsolutePath());
+ }
+
+ coreModulesFinder = ModuleFinder.of(modulesPath);
+ allCoreModules = coreModulesFinder.findAll();
+ }
+
+ @AfterClass
+ public static void cleanup() {
+ allCoreModules = null;
+ coreModulesFinder = null;
+ }
+
+ /** Make sure all published module names remain constant, even if we reorganize the build. */
+ @Test
+ public void testExpectedDistributionModuleNames() {
+ Assertions.assertThat(
+ allCoreModules.stream().map(module -> module.descriptor().name()).sorted())
+ .containsExactly(
+ "org.apache.lucene.analysis.common",
+ "org.apache.lucene.analysis.icu",
+ "org.apache.lucene.analysis.kuromoji",
+ "org.apache.lucene.analysis.morfologik",
+ "org.apache.lucene.analysis.nori",
+ "org.apache.lucene.analysis.opennlp",
+ "org.apache.lucene.analysis.phonetic",
+ "org.apache.lucene.analysis.smartcn",
+ "org.apache.lucene.analysis.stempel",
+ "org.apache.lucene.backward_codecs",
+ "org.apache.lucene.benchmark",
+ "org.apache.lucene.classification",
+ "org.apache.lucene.codecs",
+ "org.apache.lucene.core",
+ "org.apache.lucene.demo",
+ "org.apache.lucene.expressions",
+ "org.apache.lucene.facet",
+ "org.apache.lucene.grouping",
+ "org.apache.lucene.highlighter",
+ "org.apache.lucene.join",
+ "org.apache.lucene.luke",
+ "org.apache.lucene.memory",
+ "org.apache.lucene.misc",
+ "org.apache.lucene.monitor",
+ "org.apache.lucene.queries",
+ "org.apache.lucene.queryparser",
+ "org.apache.lucene.replicator",
+ "org.apache.lucene.sandbox",
+ "org.apache.lucene.spatial3d",
+ "org.apache.lucene.spatial_extras",
+ "org.apache.lucene.suggest");
+ }
+
+ /** Make sure we don't publish automatic modules. */
+ @Test
+ public void testAllCoreModulesAreNamedModules() {
+ Assertions.assertThat(allCoreModules)
+ .allSatisfy(
+ module -> {
+ Assertions.assertThat(module.descriptor().isAutomatic())
+ .as(module.descriptor().name())
+ .isFalse();
+ });
+ }
+
+ /** Ensure all modules have the same (expected) version. */
+ @Test
+ public void testAllModulesHaveExpectedVersion() {
+ String luceneBuildVersion = System.getProperty(VERSION_PROPERTY);
+ Assumptions.assumeThat(luceneBuildVersion).isNotNull();
+ for (var module : allCoreModules) {
+ Assertions.assertThat(module.descriptor().rawVersion().orElse(null))
+ .as("Version of module: " + module.descriptor().name())
+ .isEqualTo(luceneBuildVersion);
+ }
+ }
+
+ /** Ensure SPIs are equal for the module and classpath layer. */
+ @Test
+ public void testModularAndClasspathProvidersAreConsistent() throws IOException {
+ for (var module : allCoreModules) {
+ TreeMap<String, TreeSet<String>> modularProviders = getModularServiceProviders(module);
+ TreeMap<String, TreeSet<String>> classpathProviders = getClasspathServiceProviders(module);
+
+ // Compare services first so that the exception is shorter.
+ Assertions.assertThat(modularProviders.keySet())
+ .as("Modular services in module: " + module.descriptor().name())
+ .containsExactlyInAnyOrderElementsOf(classpathProviders.keySet());
+
+ // We're sure the services correspond to each other. Now, for each service, compare the
+ // providers.
+ for (var service : modularProviders.keySet()) {
+ Assertions.assertThat(modularProviders.get(service))
+ .as(
+ "Modular providers of service "
+ + service
+ + " in module: "
+ + module.descriptor().name())
+ .containsExactlyInAnyOrderElementsOf(classpathProviders.get(service));
+ }
+ }
+ }
+
+ private TreeMap<String, TreeSet<String>> getClasspathServiceProviders(ModuleReference module)
+ throws IOException {
+ TreeMap<String, TreeSet<String>> services = new TreeMap<>();
+ Pattern serviceEntryPattern = Pattern.compile("META-INF/services/(?<serviceName>.+)");
+ try (ModuleReader reader = module.open();
+ Stream<String> entryStream = reader.list()) {
+ List<String> serviceProviderEntryList =
+ entryStream
+ .filter(entry -> serviceEntryPattern.matcher(entry).find())
+ .collect(Collectors.toList());
+
+ for (String entry : serviceProviderEntryList) {
+ List<String> implementations;
+ try (InputStream is = reader.open(entry).get()) {
+ implementations =
+ Arrays.stream(new String(is.readAllBytes(), StandardCharsets.UTF_8).split("\n"))
+ .map(String::trim)
+ .filter(line -> !line.isBlank() && !line.startsWith("#"))
+ .collect(Collectors.toList());
+ }
+
+ Matcher matcher = serviceEntryPattern.matcher(entry);
+ if (!matcher.find()) {
+ throw new AssertionError("Impossible.");
+ }
+ String service = matcher.group("serviceName");
+ services.computeIfAbsent(service, k -> new TreeSet<>()).addAll(implementations);
+ }
+ }
+
+ return services;
+ }
+
+ private static TreeMap<String, TreeSet<String>> getModularServiceProviders(
+ ModuleReference module) {
+ return module.descriptor().provides().stream()
+ .collect(
+ Collectors.toMap(
+ ModuleDescriptor.Provides::service,
+ provides -> new TreeSet<>(provides.providers()),
+ (k, v) -> {
+ throw new RuntimeException();
+ },
+ TreeMap::new));
+ }
+
+ /**
+ * Ensure all exported packages in the descriptor are in sync with the module's Java classes.
+ *
+ * <p>This test should be progressively tuned so that certain internal packages are hidden in the
+ * module layer.
+ */
+ @Test
+ public void testAllOpenPackagesInSync() throws IOException {
+ for (var module : allCoreModules) {
+ Set<String> jarPackages = getJarPackages(module);
+
+ if (module.descriptor().name().equals("org.apache.lucene.luke")) {
+ jarPackages.removeIf(
+ entry -> {
+ // Luke's packages are not exported.
+ return entry.startsWith("org.apache.lucene.luke");
+ });
+ }
+
+ Set<ModuleDescriptor.Exports> moduleExports = module.descriptor().exports();
+ Assertions.assertThat(moduleExports)
+ .as("Exported packages in module: " + module.descriptor().name())
+ .allSatisfy(
+ export -> {
+ Assertions.assertThat(export.targets())
+ .as("We only support unqualified exports for now?")
+ .isEmpty();
+ })
+ .map(ModuleDescriptor.Exports::source)
+ .containsExactlyInAnyOrderElementsOf(jarPackages);
+ }
+ }
+
+ private Set<String> getJarPackages(ModuleReference module) throws IOException {
+ try (ModuleReader reader = module.open()) {
+ return reader
+ .list()
+ .filter(
+ entry ->
+ !entry.startsWith("META-INF/")
+ && !entry.equals("module-info.class")
+ && !entry.endsWith("/"))
+ .map(entry -> entry.replaceAll("/[^/]+$", ""))
+ .map(entry -> entry.replace('/', '.'))
+ .collect(Collectors.toCollection(TreeSet::new));
+ }
+ }
+}
diff --git a/lucene/distribution/binary-release.gradle b/lucene/distribution/binary-release.gradle
index c06bb1a..be2ae60 100644
--- a/lucene/distribution/binary-release.gradle
+++ b/lucene/distribution/binary-release.gradle
@@ -28,6 +28,8 @@ configure(project(":lucene:distribution")) {
jars
jarsTestFramework
jarsThirdParty
+
+ binaryDirForTests
}
dependencies { DependencyHandler handler ->
@@ -63,7 +65,6 @@ configure(project(":lucene:distribution")) {
}
}
-
task assembleBinaryTgz(type: Tar) {
description "Assemble binary Lucene artifact as a .tgz file."
@@ -73,6 +74,26 @@ configure(project(":lucene:distribution")) {
reproducibleFileOrder = true
compression = Compression.GZIP
+ // Internal archive folder for all files.
+ into "lucene-${rootProject.version}/"
+ }
+
+ task assembleBinaryDirForTests(type: Sync) {
+ description "Assemble a subset of the binary Lucene distribution as an expanded directory for tests."
+
+ destinationDir file("${packageBaseName}-itests")
+ }
+
+ artifacts {
+ binaryDirForTests tasks.assembleBinaryDirForTests.destinationDir, {
+ builtBy tasks.assembleBinaryDirForTests
+ }
+ }
+
+ // Configure distribution content for archives and stand-alone directories.
+ // This is split into binaries and other artifacts to speed up distribution
+ // tests.
+ Closure<Void> distributionBinaryContent = { AbstractCopyTask task ->
// Manually correct posix permissions (matters when assembling archives on Windows).
filesMatching(["**/*.sh", "**/*.bat"]) { copy ->
copy.setMode(0755)
@@ -83,6 +104,21 @@ configure(project(":lucene:distribution")) {
filteringCharset = 'UTF-8'
})
+ // Binary modules (Lucene).
+ from(configurations.jars, {
+ into 'modules'
+ })
+ from(configurations.jarsTestFramework, {
+ into 'modules-test-framework'
+ })
+
+ // Binary modules (with dependencies). Don't duplicate project artifacts.
+ from((configurations.jarsThirdParty - configurations.jars), {
+ into 'modules-thirdparty'
+ })
+ }
+
+ Closure<Void> distributionOtherContent = { AbstractCopyTask task ->
// Cherry-pick certain files from the root.
from(project(':').projectDir, {
include "LICENSE.txt"
@@ -102,21 +138,14 @@ configure(project(":lucene:distribution")) {
from(configurations.docs, {
into 'docs'
})
+ }
- // Binary modules (Lucene).
- from(configurations.jars, {
- into 'modules'
- })
- from(configurations.jarsTestFramework, {
- into 'modules-test-framework'
- })
-
- // Binary modules (with dependencies). Don't duplicate project artifacts.
- from((configurations.jarsThirdParty - configurations.jars), {
- into 'modules-thirdparty'
- })
+ [tasks.assembleBinaryTgz].each { Task task ->
+ task.configure distributionBinaryContent
+ task.configure distributionOtherContent
+ }
- // Internal archive folder for all files.
- into "lucene-${rootProject.version}/"
+ [tasks.assembleBinaryDirForTests].each { Task task ->
+ task.configure distributionBinaryContent
}
}
diff --git a/lucene/distribution/src/binary-release/bin/luke.cmd b/lucene/distribution/src/binary-release/bin/luke.cmd
index b4591ae..ee5d06c 100644
--- a/lucene/distribution/src/binary-release/bin/luke.cmd
+++ b/lucene/distribution/src/binary-release/bin/luke.cmd
@@ -17,5 +17,5 @@
SETLOCAL
SET MODULES=%~dp0..
-start javaw --module-path "%MODULES%\modules;%MODULES%\modules-thirdparty" --add-modules jdk.unsupported --module org.apache.lucene.luke
+start javaw --module-path "%MODULES%\modules;%MODULES%\modules-thirdparty" --module org.apache.lucene.luke
ENDLOCAL
diff --git a/lucene/distribution/src/binary-release/bin/luke.sh b/lucene/distribution/src/binary-release/bin/luke.sh
index 053edda..b934f4e 100644
--- a/lucene/distribution/src/binary-release/bin/luke.sh
+++ b/lucene/distribution/src/binary-release/bin/luke.sh
@@ -17,4 +17,4 @@
MODULES=`dirname "$0"`/..
MODULES=`cd "$MODULES" && pwd`
-java --module-path "$MODULES/modules:$MODULES/modules-thirdparty" --add-modules jdk.unsupported --module org.apache.lucene.luke
+java --module-path "$MODULES/modules:$MODULES/modules-thirdparty" --module org.apache.lucene.luke
diff --git a/lucene/expressions/build.gradle b/lucene/expressions/build.gradle
index 7ba76a7..6823ae6 100644
--- a/lucene/expressions/build.gradle
+++ b/lucene/expressions/build.gradle
@@ -20,21 +20,14 @@ apply plugin: 'java-library'
description = 'Dynamically computed values to sort/facet/search on based on a pluggable grammar'
dependencies {
- api project(':lucene:core')
+ moduleApi project(':lucene:core')
- implementation project(':lucene:codecs')
+ moduleImplementation project(':lucene:codecs')
- implementation 'org.antlr:antlr4-runtime'
+ moduleImplementation 'org.antlr:antlr4-runtime'
- // It is awkward that we force-omit the intermediate dependency here...
- // The dependency chain is:
- // asm-commons -> asm-tree -> asm
- // Should we really go through these hoops?
- implementation 'org.ow2.asm:asm'
- implementation('org.ow2.asm:asm-commons', {
- exclude group: "org.ow2.asm", module: "asm-tree"
- exclude group: "org.ow2.asm", module: "asm-analysis"
- })
+ moduleImplementation 'org.ow2.asm:asm'
+ moduleImplementation 'org.ow2.asm:asm-commons'
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/analysis/icu/build.gradle b/lucene/expressions/src/java/module-info.java
similarity index 70%
copy from lucene/analysis/icu/build.gradle
copy to lucene/expressions/src/java/module-info.java
index 2eab963..108f453 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/expressions/src/java/module-info.java
@@ -15,15 +15,14 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+@SuppressWarnings({"requires-automatic"})
+module org.apache.lucene.expressions {
+ requires org.objectweb.asm;
+ requires org.objectweb.asm.commons;
+ requires antlr4.runtime;
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.codecs;
-description = 'Analysis integration with ICU (International Components for Unicode)'
-
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'com.ibm.icu:icu4j'
-
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.expressions;
+ exports org.apache.lucene.expressions.js;
}
diff --git a/lucene/facet/build.gradle b/lucene/facet/build.gradle
index b4f3ac5..1b16f94 100644
--- a/lucene/facet/build.gradle
+++ b/lucene/facet/build.gradle
@@ -20,10 +20,10 @@ apply plugin: 'java-library'
description = 'Faceted indexing and search capabilities'
-dependencies {
- api project(':lucene:core')
+dependencies {
+ moduleApi project(':lucene:core')
- implementation 'com.carrotsearch:hppc'
+ moduleImplementation 'com.carrotsearch:hppc'
testImplementation project(':lucene:test-framework')
testImplementation project(':lucene:queries')
diff --git a/lucene/analysis/morfologik/build.gradle b/lucene/facet/src/java/module-info.java
similarity index 62%
copy from lucene/analysis/morfologik/build.gradle
copy to lucene/facet/src/java/module-info.java
index 153515f..26859cc 100644
--- a/lucene/analysis/morfologik/build.gradle
+++ b/lucene/facet/src/java/module-info.java
@@ -15,18 +15,17 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Faceted indexing and search capabilities */
+@SuppressWarnings({"requires-automatic"})
+module org.apache.lucene.facet {
+ requires java.logging;
+ requires com.carrotsearch.hppc;
+ requires org.apache.lucene.core;
-description = 'Analyzer for dictionary stemming, built-in Polish dictionary'
-
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'org.carrot2:morfologik-stemming'
-
- implementation 'org.carrot2:morfologik-polish'
- implementation 'ua.net.nlp:morfologik-ukrainian-search'
-
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.facet;
+ exports org.apache.lucene.facet.range;
+ exports org.apache.lucene.facet.sortedset;
+ exports org.apache.lucene.facet.taxonomy;
+ exports org.apache.lucene.facet.taxonomy.directory;
+ exports org.apache.lucene.facet.taxonomy.writercache;
}
diff --git a/lucene/grouping/build.gradle b/lucene/grouping/build.gradle
index 6e71964..7035a11 100644
--- a/lucene/grouping/build.gradle
+++ b/lucene/grouping/build.gradle
@@ -21,9 +21,9 @@ apply plugin: 'java-library'
description = 'Collectors for grouping search results'
dependencies {
- api project(':lucene:core')
+ moduleApi project(':lucene:core')
- implementation project(':lucene:queries')
+ moduleImplementation project(':lucene:queries')
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/backward-codecs/build.gradle b/lucene/grouping/src/java/module-info.java
similarity index 80%
copy from lucene/backward-codecs/build.gradle
copy to lucene/grouping/src/java/module-info.java
index aa47302..0f9665e 100644
--- a/lucene/backward-codecs/build.gradle
+++ b/lucene/grouping/src/java/module-info.java
@@ -15,12 +15,10 @@
* limitations under the License.
*/
+/** Collectors for grouping search results */
+module org.apache.lucene.grouping {
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.queries;
-apply plugin: 'java-library'
-
-description = 'Codecs for older versions of Lucene'
-
-dependencies {
- api project(':lucene:core')
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.search.grouping;
}
diff --git a/lucene/highlighter/build.gradle b/lucene/highlighter/build.gradle
index 6bd8426..105f1de 100644
--- a/lucene/highlighter/build.gradle
+++ b/lucene/highlighter/build.gradle
@@ -21,10 +21,10 @@ apply plugin: 'java-library'
description = 'Highlights search keywords in results'
dependencies {
- api project(':lucene:core')
+ moduleApi project(':lucene:core')
- implementation project(':lucene:queries')
- implementation project(':lucene:memory')
+ moduleImplementation project(':lucene:queries')
+ moduleImplementation project(':lucene:memory')
testImplementation project(':lucene:test-framework')
testImplementation project(':lucene:analysis:common')
diff --git a/lucene/analysis/icu/build.gradle b/lucene/highlighter/src/java/module-info.java
similarity index 67%
copy from lucene/analysis/icu/build.gradle
copy to lucene/highlighter/src/java/module-info.java
index 2eab963..64da8b5 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/highlighter/src/java/module-info.java
@@ -15,15 +15,14 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Highlights search keywords in results */
+module org.apache.lucene.highlighter {
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.queries;
+ requires org.apache.lucene.memory;
-description = 'Analysis integration with ICU (International Components for Unicode)'
-
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'com.ibm.icu:icu4j'
-
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.search.highlight;
+ exports org.apache.lucene.search.matchhighlight;
+ exports org.apache.lucene.search.uhighlight;
+ exports org.apache.lucene.search.vectorhighlight;
}
diff --git a/lucene/join/build.gradle b/lucene/join/build.gradle
index 143daa1..d8c2eab 100644
--- a/lucene/join/build.gradle
+++ b/lucene/join/build.gradle
@@ -20,6 +20,6 @@ apply plugin: 'java-library'
description = 'Index-time and Query-time joins for normalized content'
dependencies {
- api project(':lucene:core')
+ moduleApi project(':lucene:core')
testImplementation project(':lucene:test-framework')
}
\ No newline at end of file
diff --git a/lucene/backward-codecs/build.gradle b/lucene/join/src/java/module-info.java
similarity index 81%
copy from lucene/backward-codecs/build.gradle
copy to lucene/join/src/java/module-info.java
index aa47302..80d2261 100644
--- a/lucene/backward-codecs/build.gradle
+++ b/lucene/join/src/java/module-info.java
@@ -15,12 +15,9 @@
* limitations under the License.
*/
+/** Index-time and Query-time joins for normalized content */
+module org.apache.lucene.join {
+ requires org.apache.lucene.core;
-apply plugin: 'java-library'
-
-description = 'Codecs for older versions of Lucene'
-
-dependencies {
- api project(':lucene:core')
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.search.join;
}
diff --git a/lucene/licenses/asm-analysis-7.2.jar.sha1 b/lucene/licenses/asm-analysis-7.2.jar.sha1
new file mode 100644
index 0000000..b0a8b7b
--- /dev/null
+++ b/lucene/licenses/asm-analysis-7.2.jar.sha1
@@ -0,0 +1 @@
+b6e6abe057f23630113f4167c34bda7086691258
diff --git a/lucene/licenses/asm-tree-7.2.jar.sha1 b/lucene/licenses/asm-tree-7.2.jar.sha1
new file mode 100644
index 0000000..077d6f9
--- /dev/null
+++ b/lucene/licenses/asm-tree-7.2.jar.sha1
@@ -0,0 +1 @@
+3a23cc36edaf8fc5a89cb100182758ccb5991487
diff --git a/lucene/licenses/assertj-core-3.21.0.jar.sha1 b/lucene/licenses/assertj-core-3.21.0.jar.sha1
new file mode 100644
index 0000000..9108259
--- /dev/null
+++ b/lucene/licenses/assertj-core-3.21.0.jar.sha1
@@ -0,0 +1 @@
+27a14d6d22c4e3d58f799fb2a5ca8eaf53e6942a
diff --git a/lucene/licenses/assertj-core-LICENSE-ASL.txt b/lucene/licenses/assertj-core-LICENSE-ASL.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/lucene/licenses/assertj-core-LICENSE-ASL.txt
@@ -0,0 +1,201 @@
+ 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/lucene/licenses/assertj-core-NOTICE.txt b/lucene/licenses/assertj-core-NOTICE.txt
new file mode 100644
index 0000000..e69de29
diff --git a/lucene/luke/build.gradle b/lucene/luke/build.gradle
index fe556ca..6def3e6 100644
--- a/lucene/luke/build.gradle
+++ b/lucene/luke/build.gradle
@@ -25,25 +25,25 @@ ext {
}
dependencies {
- api project(':lucene:core')
-
- implementation project(':lucene:codecs')
- implementation project(':lucene:backward-codecs')
- implementation project(':lucene:analysis:common')
- implementation project(':lucene:queries')
- implementation project(':lucene:queryparser')
- implementation project(':lucene:misc')
-
- implementation project(":lucene:highlighter")
- implementation project(':lucene:analysis:icu')
- implementation project(':lucene:analysis:kuromoji')
- implementation project(':lucene:analysis:morfologik')
- implementation project(':lucene:analysis:nori')
- implementation project(':lucene:analysis:opennlp')
- implementation project(':lucene:analysis:phonetic')
- implementation project(':lucene:analysis:smartcn')
- implementation project(':lucene:analysis:stempel')
- implementation project(':lucene:suggest')
+ moduleApi project(':lucene:core')
+
+ moduleImplementation project(':lucene:codecs')
+ moduleImplementation project(':lucene:backward-codecs')
+ moduleImplementation project(':lucene:analysis:common')
+ moduleImplementation project(':lucene:queries')
+ moduleImplementation project(':lucene:queryparser')
+ moduleImplementation project(':lucene:misc')
+
+ moduleImplementation project(":lucene:highlighter")
+ moduleImplementation project(':lucene:analysis:icu')
+ moduleImplementation project(':lucene:analysis:kuromoji')
+ moduleImplementation project(':lucene:analysis:morfologik')
+ moduleImplementation project(':lucene:analysis:nori')
+ moduleImplementation project(':lucene:analysis:opennlp')
+ moduleImplementation project(':lucene:analysis:phonetic')
+ moduleImplementation project(':lucene:analysis:smartcn')
+ moduleImplementation project(':lucene:analysis:stempel')
+ moduleImplementation project(':lucene:suggest')
testImplementation project(':lucene:test-framework')
}
@@ -55,6 +55,11 @@ tasks.withType(Jar) {
}
}
+// Configure the main class and version attribute for the module system.
+tasks.compileJava.configure {
+ options.javaModuleMainClass.set("org.apache.lucene.luke.app.desktop.LukeMain")
+}
+
// Process UTF8 property files to unicode escapes.
tasks.withType(ProcessResources).configureEach { task ->
task.filesMatching("**/messages*.properties", {
@@ -105,8 +110,13 @@ task standaloneAssemble(type: Sync) {
into standaloneDistDir
doLast {
- logger.lifecycle("Standalone Luke distribution assembled. You can run it with:\n"
- + "java -jar " + file("${standaloneDistDir}/${standaloneJar.archiveFileName.get()}"))
+ logger.lifecycle(
+ """
+Standalone Luke distribution assembled. You can run it with:
+java -jar "${standaloneDistDir}/${standaloneJar.archiveFileName.get()}"
+java --module-path "${standaloneDistDir}" -m org.apache.lucene.luke
+ """
+ )
}
}
@@ -141,3 +151,4 @@ task run() {
}
}
}
+
diff --git a/lucene/analysis/icu/build.gradle b/lucene/luke/src/java/module-info.java
similarity index 71%
copy from lucene/analysis/icu/build.gradle
copy to lucene/luke/src/java/module-info.java
index 2eab963..101d4ae 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/luke/src/java/module-info.java
@@ -15,15 +15,13 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
-
-description = 'Analysis integration with ICU (International Components for Unicode)'
-
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'com.ibm.icu:icu4j'
-
- testImplementation project(':lucene:test-framework')
+/** Luke : Lucene toolbox project. */
+module org.apache.lucene.luke {
+ requires java.desktop;
+ requires java.logging;
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
+ requires org.apache.lucene.queries;
+ requires org.apache.lucene.queryparser;
+ requires org.apache.lucene.misc;
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/LukeMain.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/LukeMain.java
index f64ec18..cd78468 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/LukeMain.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/LukeMain.java
@@ -20,8 +20,8 @@ package org.apache.lucene.luke.app.desktop;
import static org.apache.lucene.luke.app.desktop.util.ExceptionHandler.handle;
import java.awt.GraphicsEnvironment;
-import java.io.IOException;
import java.lang.invoke.MethodHandles;
+import java.util.concurrent.SynchronousQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
@@ -48,19 +48,19 @@ public class LukeMain {
return frame;
}
- private static void createAndShowGUI() {
+ /** @return Returns {@code true} if GUI startup and initialization was successful. */
+ private static boolean createAndShowGUI() {
// uncaught error handler
MessageBroker messageBroker = MessageBroker.getInstance();
- Thread.setDefaultUncaughtExceptionHandler((thread, cause) -> handle(cause, messageBroker));
-
try {
+ Thread.setDefaultUncaughtExceptionHandler((thread, cause) -> handle(cause, messageBroker));
+
frame = new LukeWindowProvider().get();
frame.setLocation(200, 100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
- // show open index dialog
OpenIndexDialogFactory openIndexDialogFactory = OpenIndexDialogFactory.getInstance();
new DialogOpener<>(openIndexDialogFactory)
.open(
@@ -68,9 +68,12 @@ public class LukeMain {
600,
420,
(factory) -> {});
- } catch (IOException e) {
+
+ return true;
+ } catch (Throwable e) {
messageBroker.showUnknownErrorMessage();
log.log(Level.SEVERE, "Cannot initialize components.", e);
+ return false;
}
}
@@ -86,6 +89,19 @@ public class LukeMain {
GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment();
genv.registerFont(FontUtils.createElegantIconFont());
- javax.swing.SwingUtilities.invokeLater(LukeMain::createAndShowGUI);
+ var guiThreadResult = new SynchronousQueue<Boolean>();
+ javax.swing.SwingUtilities.invokeLater(
+ () -> {
+ try {
+ guiThreadResult.put(createAndShowGUI());
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+ if (Boolean.FALSE.equals(guiThreadResult.take())) {
+ Logger.getGlobal().log(Level.SEVERE, "Luke could not start.");
+ Runtime.getRuntime().exit(1);
+ }
}
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/FontUtils.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/FontUtils.java
index 02c201e..90f5c2c 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/FontUtils.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/FontUtils.java
@@ -27,9 +27,7 @@ import javax.swing.JLabel;
/** Font utilities */
public class FontUtils {
-
- public static final String TTF_RESOURCE_NAME =
- "org/apache/lucene/luke/app/desktop/font/ElegantIcons.ttf";
+ private static final String TTF_RESOURCE_NAME = "ElegantIcons.ttf";
@SuppressWarnings("unchecked")
public static JLabel toLinkText(JLabel label) {
@@ -42,7 +40,7 @@ public class FontUtils {
}
public static Font createElegantIconFont() throws IOException, FontFormatException {
- InputStream is = FontUtils.class.getClassLoader().getResourceAsStream(TTF_RESOURCE_NAME);
+ InputStream is = FontUtils.class.getResourceAsStream(TTF_RESOURCE_NAME);
return Font.createFont(Font.TRUETYPE_FONT, is);
}
diff --git a/lucene/luke/src/resources/org/apache/lucene/luke/app/desktop/font/ElegantIcons.ttf b/lucene/luke/src/resources/org/apache/lucene/luke/app/desktop/util/ElegantIcons.ttf
similarity index 100%
rename from lucene/luke/src/resources/org/apache/lucene/luke/app/desktop/font/ElegantIcons.ttf
rename to lucene/luke/src/resources/org/apache/lucene/luke/app/desktop/util/ElegantIcons.ttf
diff --git a/lucene/memory/build.gradle b/lucene/memory/build.gradle
index 0d3bc1f..eb6626e 100644
--- a/lucene/memory/build.gradle
+++ b/lucene/memory/build.gradle
@@ -21,7 +21,7 @@ apply plugin: 'java-library'
description = 'Single-document in-memory index implementation'
dependencies {
- api project(':lucene:core')
+ moduleApi project(':lucene:core')
testImplementation project(':lucene:test-framework')
testImplementation project(':lucene:queryparser')
diff --git a/lucene/backward-codecs/build.gradle b/lucene/memory/src/java/module-info.java
similarity index 81%
copy from lucene/backward-codecs/build.gradle
copy to lucene/memory/src/java/module-info.java
index aa47302..1d4f84a 100644
--- a/lucene/backward-codecs/build.gradle
+++ b/lucene/memory/src/java/module-info.java
@@ -15,12 +15,9 @@
* limitations under the License.
*/
+/** Single-document in-memory index implementation */
+module org.apache.lucene.memory {
+ requires org.apache.lucene.core;
-apply plugin: 'java-library'
-
-description = 'Codecs for older versions of Lucene'
-
-dependencies {
- api project(':lucene:core')
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.index.memory;
}
diff --git a/lucene/misc/build.gradle b/lucene/misc/build.gradle
index efed4f2..b9d7626 100644
--- a/lucene/misc/build.gradle
+++ b/lucene/misc/build.gradle
@@ -20,7 +20,7 @@ apply plugin: 'java-library'
description = 'Index tools and other miscellaneous code'
dependencies {
- api project(':lucene:core')
+ moduleApi project(':lucene:core')
testImplementation project(':lucene:test-framework')
nativeDeps project(":lucene:misc:native")
diff --git a/lucene/analysis/icu/build.gradle b/lucene/misc/src/java/module-info.java
similarity index 67%
copy from lucene/analysis/icu/build.gradle
copy to lucene/misc/src/java/module-info.java
index 2eab963..269e6b0 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/misc/src/java/module-info.java
@@ -15,15 +15,15 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Index tools and other miscellaneous code */
+module org.apache.lucene.misc {
+ requires org.apache.lucene.core;
-description = 'Analysis integration with ICU (International Components for Unicode)'
-
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'com.ibm.icu:icu4j'
-
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.misc;
+ exports org.apache.lucene.misc.document;
+ exports org.apache.lucene.misc.index;
+ exports org.apache.lucene.misc.search;
+ exports org.apache.lucene.misc.store;
+ exports org.apache.lucene.misc.util;
+ exports org.apache.lucene.misc.util.fst;
}
diff --git a/lucene/monitor/build.gradle b/lucene/monitor/build.gradle
index 3dd65a4..ff6677f 100644
--- a/lucene/monitor/build.gradle
+++ b/lucene/monitor/build.gradle
@@ -20,10 +20,10 @@ apply plugin: 'java-library'
description = 'Reverse-search implementation for monitoring and classification'
dependencies {
- api project(':lucene:core')
+ moduleApi project(':lucene:core')
- implementation project(':lucene:memory')
- implementation project(':lucene:analysis:common')
+ moduleImplementation project(':lucene:memory')
+ moduleImplementation project(':lucene:analysis:common')
testImplementation project(':lucene:queryparser')
testImplementation project(':lucene:test-framework')
diff --git a/lucene/analysis/stempel/build.gradle b/lucene/monitor/src/java/module-info.java
similarity index 75%
copy from lucene/analysis/stempel/build.gradle
copy to lucene/monitor/src/java/module-info.java
index 3b80f9f..71b70f0 100644
--- a/lucene/analysis/stempel/build.gradle
+++ b/lucene/monitor/src/java/module-info.java
@@ -15,13 +15,11 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Reverse-search implementation for monitoring and classification */
+module org.apache.lucene.monitor {
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
+ requires org.apache.lucene.memory;
-description = 'Analyzer for indexing Polish'
-
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.monitor;
}
diff --git a/lucene/queries/build.gradle b/lucene/queries/build.gradle
index bd56a4d..d0cc010 100644
--- a/lucene/queries/build.gradle
+++ b/lucene/queries/build.gradle
@@ -20,7 +20,7 @@ apply plugin: 'java-library'
description = 'Filters and Queries that add to core Lucene'
dependencies {
- api project(':lucene:core')
+ moduleApi project(':lucene:core')
testImplementation project(':lucene:test-framework')
testImplementation project(':lucene:expressions')
diff --git a/lucene/analysis/morfologik/build.gradle b/lucene/queries/src/java/module-info.java
similarity index 61%
copy from lucene/analysis/morfologik/build.gradle
copy to lucene/queries/src/java/module-info.java
index 153515f..ae3ff4d 100644
--- a/lucene/analysis/morfologik/build.gradle
+++ b/lucene/queries/src/java/module-info.java
@@ -15,18 +15,16 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Filters and Queries that add to core Lucene */
+module org.apache.lucene.queries {
+ requires org.apache.lucene.core;
-description = 'Analyzer for dictionary stemming, built-in Polish dictionary'
-
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'org.carrot2:morfologik-stemming'
-
- implementation 'org.carrot2:morfologik-polish'
- implementation 'ua.net.nlp:morfologik-ukrainian-search'
-
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.queries;
+ exports org.apache.lucene.queries.function;
+ exports org.apache.lucene.queries.function.docvalues;
+ exports org.apache.lucene.queries.function.valuesource;
+ exports org.apache.lucene.queries.intervals;
+ exports org.apache.lucene.queries.mlt;
+ exports org.apache.lucene.queries.payloads;
+ exports org.apache.lucene.queries.spans;
}
diff --git a/lucene/queryparser/build.gradle b/lucene/queryparser/build.gradle
index 077eb24..b50b565 100644
--- a/lucene/queryparser/build.gradle
+++ b/lucene/queryparser/build.gradle
@@ -20,9 +20,9 @@ apply plugin: 'java-library'
description = 'Query parsers and parsing framework'
dependencies {
- api project(':lucene:core')
- api project(':lucene:queries')
- api project(':lucene:sandbox')
+ moduleApi project(':lucene:core')
+ moduleApi project(':lucene:queries')
+ moduleApi project(':lucene:sandbox')
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/queryparser/src/java/module-info.java b/lucene/queryparser/src/java/module-info.java
new file mode 100644
index 0000000..3dab16d
--- /dev/null
+++ b/lucene/queryparser/src/java/module-info.java
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/** Query parsers and parsing framework */
+module org.apache.lucene.queryparser {
+ requires java.xml;
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.queries;
+ requires org.apache.lucene.sandbox;
+
+ exports org.apache.lucene.queryparser.charstream;
+ exports org.apache.lucene.queryparser.classic;
+ exports org.apache.lucene.queryparser.complexPhrase;
+ exports org.apache.lucene.queryparser.ext;
+ exports org.apache.lucene.queryparser.flexible.core;
+ exports org.apache.lucene.queryparser.flexible.core.builders;
+ exports org.apache.lucene.queryparser.flexible.core.config;
+ exports org.apache.lucene.queryparser.flexible.core.messages;
+ exports org.apache.lucene.queryparser.flexible.core.nodes;
+ exports org.apache.lucene.queryparser.flexible.core.parser;
+ exports org.apache.lucene.queryparser.flexible.core.processors;
+ exports org.apache.lucene.queryparser.flexible.core.util;
+ exports org.apache.lucene.queryparser.flexible.messages;
+ exports org.apache.lucene.queryparser.flexible.precedence;
+ exports org.apache.lucene.queryparser.flexible.precedence.processors;
+ exports org.apache.lucene.queryparser.flexible.standard;
+ exports org.apache.lucene.queryparser.flexible.standard.builders;
+ exports org.apache.lucene.queryparser.flexible.standard.config;
+ exports org.apache.lucene.queryparser.flexible.standard.nodes;
+ exports org.apache.lucene.queryparser.flexible.standard.nodes.intervalfn;
+ exports org.apache.lucene.queryparser.flexible.standard.parser;
+ exports org.apache.lucene.queryparser.flexible.standard.processors;
+ exports org.apache.lucene.queryparser.simple;
+ exports org.apache.lucene.queryparser.surround.parser;
+ exports org.apache.lucene.queryparser.surround.query;
+ exports org.apache.lucene.queryparser.xml;
+ exports org.apache.lucene.queryparser.xml.builders;
+}
diff --git a/lucene/replicator/build.gradle b/lucene/replicator/build.gradle
index c51feb0..d3dfc07 100644
--- a/lucene/replicator/build.gradle
+++ b/lucene/replicator/build.gradle
@@ -20,15 +20,15 @@ apply plugin: 'java-library'
description = 'Lucene index files replication utility'
dependencies {
- api project(':lucene:core')
+ moduleApi project(':lucene:core')
- implementation project(':lucene:facet')
+ moduleImplementation project(':lucene:facet')
- implementation('org.apache.httpcomponents:httpclient', {
+ moduleImplementation('org.apache.httpcomponents:httpclient', {
exclude group: "commons-codec", module: "commons-codec"
})
- implementation 'javax.servlet:javax.servlet-api'
+ moduleImplementation 'javax.servlet:javax.servlet-api'
testImplementation 'org.eclipse.jetty:jetty-server'
testImplementation('org.eclipse.jetty:jetty-servlet', {
diff --git a/lucene/analysis/icu/build.gradle b/lucene/replicator/src/java/module-info.java
similarity index 66%
copy from lucene/analysis/icu/build.gradle
copy to lucene/replicator/src/java/module-info.java
index 2eab963..d44b9ad 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/replicator/src/java/module-info.java
@@ -15,15 +15,15 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Lucene index files replication utility */
+@SuppressWarnings({"requires-automatic"})
+module org.apache.lucene.replicator {
+ requires javax.servlet.api;
+ requires org.apache.httpcomponents.httpclient;
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.facet;
-description = 'Analysis integration with ICU (International Components for Unicode)'
-
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'com.ibm.icu:icu4j'
-
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.replicator;
+ exports org.apache.lucene.replicator.http;
+ exports org.apache.lucene.replicator.nrt;
}
diff --git a/lucene/sandbox/build.gradle b/lucene/sandbox/build.gradle
index a1a64d1..b7e8018 100644
--- a/lucene/sandbox/build.gradle
+++ b/lucene/sandbox/build.gradle
@@ -20,7 +20,7 @@ apply plugin: 'java-library'
description = 'Various third party contributions and new ideas'
dependencies {
- api project(':lucene:core')
- api project(':lucene:queries')
+ moduleApi project(':lucene:core')
+ moduleApi project(':lucene:queries')
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/analysis/morfologik/build.gradle b/lucene/sandbox/src/java/module-info.java
similarity index 60%
copy from lucene/analysis/morfologik/build.gradle
copy to lucene/sandbox/src/java/module-info.java
index 153515f..6d19544 100644
--- a/lucene/analysis/morfologik/build.gradle
+++ b/lucene/sandbox/src/java/module-info.java
@@ -15,18 +15,17 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Various third party contributions and new ideas */
+module org.apache.lucene.sandbox {
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.queries;
-description = 'Analyzer for dictionary stemming, built-in Polish dictionary'
+ exports org.apache.lucene.payloads;
+ exports org.apache.lucene.sandbox.codecs.idversion;
+ exports org.apache.lucene.sandbox.document;
+ exports org.apache.lucene.sandbox.queries;
+ exports org.apache.lucene.sandbox.search;
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'org.carrot2:morfologik-stemming'
-
- implementation 'org.carrot2:morfologik-polish'
- implementation 'ua.net.nlp:morfologik-ukrainian-search'
-
- testImplementation project(':lucene:test-framework')
+ provides org.apache.lucene.codecs.PostingsFormat with
+ org.apache.lucene.sandbox.codecs.idversion.IDVersionPostingsFormat;
}
diff --git a/lucene/spatial-extras/build.gradle b/lucene/spatial-extras/build.gradle
index 252056b..34fa10e 100644
--- a/lucene/spatial-extras/build.gradle
+++ b/lucene/spatial-extras/build.gradle
@@ -20,16 +20,16 @@ apply plugin: 'java-library'
description = 'Geospatial search'
dependencies {
- api project(':lucene:core')
- api project(':lucene:spatial3d')
+ moduleApi project(':lucene:core')
+ moduleApi project(':lucene:spatial3d')
- api 'org.locationtech.spatial4j:spatial4j'
- api 'io.sgr:s2-geometry-library-java'
+ moduleApi 'org.locationtech.spatial4j:spatial4j'
+ moduleApi 'io.sgr:s2-geometry-library-java'
testImplementation project(':lucene:test-framework')
testImplementation testFixtures(project(':lucene:spatial3d'))
- testImplementation 'org.locationtech.jts:jts-core'
+ moduleTestImplementation 'org.locationtech.jts:jts-core'
testImplementation 'org.locationtech.spatial4j:spatial4j::tests'
}
diff --git a/lucene/analysis/icu/build.gradle b/lucene/spatial-extras/src/java/module-info.java
similarity index 53%
copy from lucene/analysis/icu/build.gradle
copy to lucene/spatial-extras/src/java/module-info.java
index 2eab963..2464761 100644
--- a/lucene/analysis/icu/build.gradle
+++ b/lucene/spatial-extras/src/java/module-info.java
@@ -15,15 +15,23 @@
* limitations under the License.
*/
-apply plugin: 'java-library'
+/** Geospatial search */
+@SuppressWarnings({"requires-automatic"})
+module org.apache.lucene.spatial_extras {
+ requires java.logging;
+ requires spatial4j;
+ requires s2.geometry.library.java;
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.spatial3d;
-description = 'Analysis integration with ICU (International Components for Unicode)'
-
-dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
-
- api 'com.ibm.icu:icu4j'
-
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.spatial;
+ exports org.apache.lucene.spatial.bbox;
+ exports org.apache.lucene.spatial.composite;
+ exports org.apache.lucene.spatial.prefix;
+ exports org.apache.lucene.spatial.prefix.tree;
+ exports org.apache.lucene.spatial.query;
+ exports org.apache.lucene.spatial.serialized;
+ exports org.apache.lucene.spatial.spatial4j;
+ exports org.apache.lucene.spatial.util;
+ exports org.apache.lucene.spatial.vector;
}
diff --git a/lucene/spatial3d/build.gradle b/lucene/spatial3d/build.gradle
index db2064c..219d029 100644
--- a/lucene/spatial3d/build.gradle
+++ b/lucene/spatial3d/build.gradle
@@ -21,7 +21,7 @@ apply plugin: 'java-test-fixtures'
description = '3D spatial planar geometry APIs'
dependencies {
- api project(':lucene:core')
+ moduleApi project(':lucene:core')
testFixturesApi project(':lucene:test-framework')
testImplementation project(':lucene:test-framework')
diff --git a/lucene/backward-codecs/build.gradle b/lucene/spatial3d/src/java/module-info.java
similarity index 80%
copy from lucene/backward-codecs/build.gradle
copy to lucene/spatial3d/src/java/module-info.java
index aa47302..9bffb23 100644
--- a/lucene/backward-codecs/build.gradle
+++ b/lucene/spatial3d/src/java/module-info.java
@@ -15,12 +15,10 @@
* limitations under the License.
*/
+/** 3D spatial planar geometry APIs */
+module org.apache.lucene.spatial3d {
+ requires org.apache.lucene.core;
-apply plugin: 'java-library'
-
-description = 'Codecs for older versions of Lucene'
-
-dependencies {
- api project(':lucene:core')
- testImplementation project(':lucene:test-framework')
+ exports org.apache.lucene.spatial3d;
+ exports org.apache.lucene.spatial3d.geom;
}
diff --git a/lucene/suggest/build.gradle b/lucene/suggest/build.gradle
index 54a5596..3afccd8 100644
--- a/lucene/suggest/build.gradle
+++ b/lucene/suggest/build.gradle
@@ -20,8 +20,8 @@ apply plugin: 'java-library'
description = 'Auto-suggest and Spellchecking support'
dependencies {
- api project(':lucene:core')
- api project(':lucene:analysis:common')
+ moduleApi project(':lucene:core')
+ moduleApi project(':lucene:analysis:common')
testImplementation project(':lucene:test-framework')
}
diff --git a/lucene/suggest/src/java/module-info.java b/lucene/suggest/src/java/module-info.java
new file mode 100644
index 0000000..4444a9dd
--- /dev/null
+++ b/lucene/suggest/src/java/module-info.java
@@ -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.
+ */
+
+/** Auto-suggest and Spellchecking support */
+module org.apache.lucene.suggest {
+ requires org.apache.lucene.core;
+ requires org.apache.lucene.analysis.common;
+
+ exports org.apache.lucene.search.spell;
+ exports org.apache.lucene.search.suggest;
+ exports org.apache.lucene.search.suggest.analyzing;
+ exports org.apache.lucene.search.suggest.document;
+ exports org.apache.lucene.search.suggest.fst;
+ exports org.apache.lucene.search.suggest.tst;
+
+ provides org.apache.lucene.codecs.PostingsFormat with
+ org.apache.lucene.search.suggest.document.Completion50PostingsFormat,
+ org.apache.lucene.search.suggest.document.Completion84PostingsFormat,
+ org.apache.lucene.search.suggest.document.Completion90PostingsFormat;
+ provides org.apache.lucene.analysis.TokenFilterFactory with
+ org.apache.lucene.search.suggest.analyzing.SuggestStopFilterFactory;
+}
diff --git a/settings.gradle b/settings.gradle
index e965095..2d48e41 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -30,6 +30,7 @@ include "lucene:analysis:common"
include "lucene:analysis:icu"
include "lucene:analysis:kuromoji"
include "lucene:analysis:morfologik"
+include "lucene:analysis:morfologik.tests"
include "lucene:analysis:nori"
include "lucene:analysis:opennlp"
include "lucene:analysis:phonetic"
@@ -41,6 +42,9 @@ include "lucene:classification"
include "lucene:codecs"
include "lucene:core"
include "lucene:demo"
+include "lucene:distribution"
+include "lucene:distribution.tests"
+include "lucene:documentation"
include "lucene:expressions"
include "lucene:facet"
include "lucene:grouping"
@@ -55,9 +59,7 @@ include "lucene:queries"
include "lucene:queryparser"
include "lucene:replicator"
include "lucene:sandbox"
-include "lucene:spatial-extras"
include "lucene:spatial3d"
+include "lucene:spatial-extras"
include "lucene:suggest"
include "lucene:test-framework"
-include "lucene:documentation"
-include "lucene:distribution"
diff --git a/versions.lock b/versions.lock
index 87c5b3f..c596e6e 100644
--- a/versions.lock
+++ b/versions.lock
@@ -18,12 +18,15 @@ org.carrot2:morfologik-polish:2.1.8 (1 constraints: 0d050036)
org.carrot2:morfologik-stemming:2.1.8 (2 constraints: 1112dc0c)
org.hamcrest:hamcrest:2.2 (1 constraints: a8041f2c)
org.locationtech.spatial4j:spatial4j:0.8 (1 constraints: ac041f2c)
-org.ow2.asm:asm:7.2 (2 constraints: 900e3e5e)
+org.ow2.asm:asm:7.2 (3 constraints: 2717d96b)
+org.ow2.asm:asm-analysis:7.2 (1 constraints: e409d9a5)
org.ow2.asm:asm-commons:7.2 (1 constraints: ad042e2c)
+org.ow2.asm:asm-tree:7.2 (2 constraints: 2f14468c)
ua.net.nlp:morfologik-ukrainian-search:4.9.1 (1 constraints: 10051b36)
xerces:xercesImpl:2.12.0 (2 constraints: 1f14b675)
[Test dependencies]
+org.assertj:assertj-core:3.21.0 (1 constraints: 38053c3b)
org.eclipse.jetty:jetty-continuation:9.4.41.v20210516 (1 constraints: 7907fe7c)
org.eclipse.jetty:jetty-http:9.4.41.v20210516 (1 constraints: f60f2ccd)
org.eclipse.jetty:jetty-io:9.4.41.v20210516 (2 constraints: 141f4566)
diff --git a/versions.props b/versions.props
index c010392..995a7dc 100644
--- a/versions.props
+++ b/versions.props
@@ -11,6 +11,7 @@ org.antlr:antlr4*=4.5.1-1
org.apache.commons:commons-compress=1.19
org.apache.httpcomponents:httpclient=4.5.13
org.apache.opennlp:opennlp-tools=1.9.1
+org.assertj:*=3.21.0
org.carrot2:morfologik-*=2.1.8
org.eclipse.jetty:*=9.4.41.v20210516
org.hamcrest:*=2.2
@@ -18,4 +19,4 @@ org.locationtech.jts:jts-core=1.17.0
org.locationtech.spatial4j:*=0.8
org.ow2.asm:*=7.2
ua.net.nlp:morfologik-ukrainian-search=4.9.1
-xerces:xercesImpl=2.12.0
+xerces:xercesImpl=2.12.0
\ No newline at end of file