mirror of https://github.com/apache/lucene.git
LUCENE-10328: Module path for compiling and running tests is wrong (#571)
This commit is contained in:
parent
c8651afde7
commit
ff547e7bbd
|
@ -57,7 +57,7 @@ allprojects {
|
|||
outputDir = project.javadoc.destinationDir
|
||||
}
|
||||
|
||||
if (project.path == ':lucene:luke' || project.path.endsWith(".tests")) {
|
||||
if (project.path == ':lucene:luke' || !(project in rootProject.ext.mavenProjects)) {
|
||||
// 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
|
||||
|
@ -165,26 +165,6 @@ configure(project(":lucene:test-framework")) {
|
|||
project.tasks.withType(RenderJavadocTask) {
|
||||
// TODO: fix missing javadocs
|
||||
javadocMissingLevel = "class"
|
||||
// TODO: clean up split packages
|
||||
javadocMissingIgnore = [
|
||||
"org.apache.lucene.analysis",
|
||||
"org.apache.lucene.analysis.standard",
|
||||
"org.apache.lucene.codecs",
|
||||
"org.apache.lucene.codecs.blockterms",
|
||||
"org.apache.lucene.codecs.bloom",
|
||||
"org.apache.lucene.codecs.compressing",
|
||||
"org.apache.lucene.codecs.uniformsplit",
|
||||
"org.apache.lucene.codecs.uniformsplit.sharedterms",
|
||||
"org.apache.lucene.geo",
|
||||
"org.apache.lucene.index",
|
||||
"org.apache.lucene.search",
|
||||
"org.apache.lucene.search.similarities",
|
||||
"org.apache.lucene.search.spans",
|
||||
"org.apache.lucene.store",
|
||||
"org.apache.lucene.util",
|
||||
"org.apache.lucene.util.automaton",
|
||||
"org.apache.lucene.util.fst"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,6 +175,13 @@ configure(project(":lucene:sandbox")) {
|
|||
}
|
||||
}
|
||||
|
||||
configure(project(":lucene:spatial-test-fixtures")) {
|
||||
project.tasks.withType(RenderJavadocTask) {
|
||||
// TODO: fix missing javadocs
|
||||
javadocMissingLevel = "class"
|
||||
}
|
||||
}
|
||||
|
||||
configure(project(":lucene:misc")) {
|
||||
project.tasks.withType(RenderJavadocTask) {
|
||||
// TODO: fix missing javadocs
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.nio.file.Path
|
||||
|
||||
// Configure miscellaneous aspects required for supporting the java module system layer.
|
||||
|
||||
// Debugging utilities.
|
||||
|
@ -27,189 +29,162 @@ allprojects {
|
|||
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'
|
||||
// Configure modular extensions for each source set.
|
||||
//
|
||||
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)
|
||||
ModularPathsExtension modularPaths = new ModularPathsExtension(project, sourceSet)
|
||||
sourceSet.extensions.add("modularPaths", modularPaths)
|
||||
|
||||
// Customized the JavaCompile for this source set so that it has proper module path.
|
||||
// LUCENE-10344: We have to provide a special-case extension for ECJ because it does not
|
||||
// support all of the module-specific javac options.
|
||||
ModularPathsExtension modularPathsForEcj = modularPaths
|
||||
if (sourceSet.name == SourceSet.TEST_SOURCE_SET_NAME && project.path in [
|
||||
":lucene:spatial-extras",
|
||||
":lucene:spatial3d",
|
||||
]) {
|
||||
modularPathsForEcj = modularPaths.cloneWithMode(ModularPathsExtension.Mode.CLASSPATH_ONLY)
|
||||
}
|
||||
sourceSet.extensions.add("modularPathsForEcj", modularPathsForEcj)
|
||||
|
||||
// TODO: the tests of these projects currently don't compile or work in
|
||||
// module-path mode. Make the modular paths extension use class path only.
|
||||
if (sourceSet.name == SourceSet.TEST_SOURCE_SET_NAME && project.path in [
|
||||
// Circular dependency between artifacts or source set outputs,
|
||||
// causing package split issues at runtime.
|
||||
":lucene:core",
|
||||
":lucene:codecs",
|
||||
":lucene:test-framework",
|
||||
]) {
|
||||
modularPaths.mode = ModularPathsExtension.Mode.CLASSPATH_ONLY
|
||||
}
|
||||
|
||||
// Configure the JavaCompile task associated with this source set.
|
||||
tasks.named(sourceSet.getCompileJavaTaskName()).configure({ JavaCompile task ->
|
||||
task.dependsOn modularPaths.compileModulePathConfiguration
|
||||
|
||||
// LUCENE-10327: don't allow gradle to emit an empty sourcepath as it would break compilation.
|
||||
// LUCENE-10327: don't allow gradle to emit an empty sourcepath as it would break
|
||||
// compilation of modules.
|
||||
task.options.setSourcepath(sourceSet.java.sourceDirectories)
|
||||
|
||||
// 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
|
||||
})
|
||||
task.options.compilerArgumentProviders.add(modularPaths.compilationArguments)
|
||||
|
||||
// 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
|
||||
})
|
||||
task.classpath = modularPaths.compilationClasspath
|
||||
}
|
||||
|
||||
doFirst {
|
||||
modularPaths.logCompilationPaths(logger)
|
||||
}
|
||||
})
|
||||
|
||||
// For source sets that contain a module descriptor, configure a jar task that combines
|
||||
// classes and resources into a single module.
|
||||
if (sourceSet.name != SourceSet.MAIN_SOURCE_SET_NAME) {
|
||||
tasks.maybeCreate(sourceSet.getJarTaskName(), org.gradle.jvm.tasks.Jar).configure({
|
||||
archiveClassifier = sourceSet.name
|
||||
from(sourceSet.output)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Connect modular configurations between their "test" and "main" source sets, this reflects
|
||||
// the conventions set by the Java plugin.
|
||||
project.configurations {
|
||||
moduleTestApi.extendsFrom moduleApi
|
||||
moduleTestImplementation.extendsFrom moduleImplementation
|
||||
moduleTestRuntimeOnly.extendsFrom moduleRuntimeOnly
|
||||
moduleTestCompileOnly.extendsFrom moduleCompileOnly
|
||||
}
|
||||
|
||||
// Gradle's java plugin sets the compile and runtime classpath to be a combination
|
||||
// of configuration dependencies and source set's outputs. For source sets with modules,
|
||||
// this leads to split class and resource folders.
|
||||
//
|
||||
// We tweak the default source set path configurations here by assembling jar task outputs
|
||||
// of the respective source set, instead of their source set output folders. We also attach
|
||||
// the main source set's jar to the modular test implementation configuration.
|
||||
SourceSet mainSourceSet = project.sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
|
||||
boolean mainIsModular = mainSourceSet.modularPaths.hasModuleDescriptor()
|
||||
boolean mainIsEmpty = mainSourceSet.allJava.isEmpty()
|
||||
SourceSet testSourceSet = project.sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME)
|
||||
boolean testIsModular = testSourceSet.modularPaths.hasModuleDescriptor()
|
||||
|
||||
// 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) {
|
||||
def jarTask = project.tasks.getByName(mainSourceSet.getJarTaskName())
|
||||
def testJarTask = project.tasks.getByName(testSourceSet.getJarTaskName())
|
||||
|
||||
// Consider various combinations of module/classpath configuration between the main and test source set.
|
||||
if (testIsModular) {
|
||||
if (mainIsModular || mainIsEmpty) {
|
||||
// If the main source set is empty, skip the jar task.
|
||||
def jarTaskOutputs = mainIsEmpty ? [] : jarTask.outputs
|
||||
|
||||
// Fully modular tests - must have no split packages, proper access, etc.
|
||||
// Work around the split classes/resources problem by adjusting classpaths to
|
||||
// rely on JARs rather than source set output folders.
|
||||
testSourceSet.compileClasspath = project.objects.fileCollection().from(
|
||||
jarTaskOutputs,
|
||||
project.configurations.getByName(testSourceSet.getCompileClasspathConfigurationName()),
|
||||
)
|
||||
testSourceSet.runtimeClasspath = project.objects.fileCollection().from(
|
||||
jarTaskOutputs,
|
||||
testJarTask.outputs,
|
||||
project.configurations.getByName(testSourceSet.getRuntimeClasspathConfigurationName()),
|
||||
)
|
||||
|
||||
project.dependencies {
|
||||
moduleTestImplementation files(jarTaskOutputs)
|
||||
moduleTestRuntimeOnly files(testJarTask.outputs)
|
||||
}
|
||||
} else {
|
||||
// This combination simply does not make any sense (in my opinion).
|
||||
throw GradleException("Test source set is modular and main source set is class-based, this makes no sense: " + project.path)
|
||||
}
|
||||
} else {
|
||||
if (mainIsModular) {
|
||||
// This combination is a potential candidate for patching the main sourceset's module with test classes. I could
|
||||
// not resolve all the difficulties that arise when you try to do it though:
|
||||
// - either a separate module descriptor is needed that opens test packages, adds dependencies via requires clauses
|
||||
// or a series of jvm arguments (--add-reads, --add-opens, etc.) has to be generated and maintained. This is
|
||||
// very low-level (ECJ doesn't support a full set of these instructions, for example).
|
||||
//
|
||||
// Fall back to classpath mode.
|
||||
} else {
|
||||
// This is the 'plain old classpath' mode: neither the main source set nor the test set are modular.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Configure the (default) test task to use module paths.
|
||||
// Configures a Test task associated with the provided source set 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()))
|
||||
ModularPathsExtension modularPaths = sourceSet.modularPaths
|
||||
|
||||
task.dependsOn modulePath
|
||||
dependsOn modularPaths
|
||||
|
||||
// Add modular dependencies and their transitive dependencies to module path.
|
||||
task.jvmArgumentProviders.add((CommandLineArgumentProvider) {
|
||||
def extraArgs = []
|
||||
jvmArgumentProviders.add(modularPaths.runtimeArguments)
|
||||
|
||||
// Determine whether the source set classes themselves should be appended
|
||||
// to classpath or module path.
|
||||
boolean sourceSetIsAModule = sourceSet.modularPaths.hasModuleDescriptor()
|
||||
// Modify the default classpath.
|
||||
classpath = modularPaths.runtimeClasspath
|
||||
|
||||
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
|
||||
})
|
||||
doFirst {
|
||||
modularPaths.logRuntimePaths(logger)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,19 +212,233 @@ allprojects {
|
|||
}
|
||||
|
||||
|
||||
class ModularPathsExtension {
|
||||
//
|
||||
// For a 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'
|
||||
//
|
||||
class ModularPathsExtension implements Cloneable, Iterable<Object> {
|
||||
/**
|
||||
* Determines how paths are split between module path and classpath.
|
||||
*/
|
||||
enum Mode {
|
||||
/**
|
||||
* Dependencies and source set outputs are placed on classpath, even if declared on modular
|
||||
* configurations. This would be the 'default' backward-compatible mode.
|
||||
*/
|
||||
CLASSPATH_ONLY,
|
||||
|
||||
/**
|
||||
* Dependencies from modular configurations are placed on module path. Source set outputs
|
||||
* are placed on classpath.
|
||||
*/
|
||||
DEPENDENCIES_ON_MODULE_PATH
|
||||
}
|
||||
|
||||
Project project
|
||||
SourceSet sourceSet
|
||||
Configuration compileModulePathConfiguration
|
||||
Configuration runtimeModulePathConfiguration
|
||||
Configuration modulePatchOnlyConfiguration
|
||||
|
||||
ModularPathsExtension(Project project, SourceSet sourceSet,
|
||||
Configuration compileModulePathConfiguration,
|
||||
Configuration runtimeModulePathConfiguration) {
|
||||
this.project = project
|
||||
// The mode of splitting paths for this source set.
|
||||
Mode mode = Mode.DEPENDENCIES_ON_MODULE_PATH
|
||||
|
||||
// More verbose debugging for paths.
|
||||
private boolean debugPaths
|
||||
|
||||
/**
|
||||
* A list of module name - path provider entries that will be converted
|
||||
* into {@code --patch-module} options.
|
||||
*/
|
||||
private List<Map.Entry<String, Provider<Path>>> modulePatches = new ArrayList<>()
|
||||
|
||||
ModularPathsExtension(Project project, SourceSet sourceSet) {
|
||||
this.project = project
|
||||
this.sourceSet = sourceSet
|
||||
this.compileModulePathConfiguration = compileModulePathConfiguration
|
||||
this.runtimeModulePathConfiguration = runtimeModulePathConfiguration
|
||||
|
||||
debugPaths = Boolean.parseBoolean(project.propertyOrDefault('build.debug.paths', 'false'))
|
||||
|
||||
ConfigurationContainer configurations = project.configurations
|
||||
|
||||
// Create modular configurations for gradle's java plugin convention configurations.
|
||||
Configuration moduleApi = createModuleConfigurationForConvention(sourceSet.apiConfigurationName)
|
||||
Configuration moduleImplementation = createModuleConfigurationForConvention(sourceSet.implementationConfigurationName)
|
||||
Configuration moduleRuntimeOnly = createModuleConfigurationForConvention(sourceSet.runtimeOnlyConfigurationName)
|
||||
Configuration moduleCompileOnly = createModuleConfigurationForConvention(sourceSet.compileOnlyConfigurationName)
|
||||
|
||||
|
||||
// Apply hierarchy relationships to modular configurations.
|
||||
moduleImplementation.extendsFrom(moduleApi)
|
||||
|
||||
// Patched modules have to end up in the implementation configuration for IDEs, which
|
||||
// otherwise get terribly confused.
|
||||
Configuration modulePatchOnly = createModuleConfigurationForConvention(
|
||||
SourceSet.isMain(sourceSet) ? "patchOnly" : sourceSet.name + "PatchOnly")
|
||||
modulePatchOnly.canBeResolved(true)
|
||||
moduleImplementation.extendsFrom(modulePatchOnly)
|
||||
this.modulePatchOnlyConfiguration = modulePatchOnly
|
||||
|
||||
// This part of convention configurations seems like a very esoteric use case, leave out for now.
|
||||
// sourceSet.compileOnlyApiConfigurationName
|
||||
|
||||
// We have to ensure configurations are using assembled resources and classes (jar variant) as a single
|
||||
// module can't be expanded into multiple folders.
|
||||
Closure<Void> ensureJarVariant = { Configuration c ->
|
||||
c.attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements, LibraryElements.JAR))
|
||||
}
|
||||
|
||||
// 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)
|
||||
ensureJarVariant(moduleConfiguration)
|
||||
|
||||
project.logger.info("Created resolvable module configuration for '${conventionConfiguration.name}': ${moduleConfiguration.name}")
|
||||
return moduleConfiguration
|
||||
}
|
||||
|
||||
ensureJarVariant(configurations.maybeCreate(sourceSet.compileClasspathConfigurationName))
|
||||
ensureJarVariant(configurations.maybeCreate(sourceSet.runtimeClasspathConfigurationName))
|
||||
|
||||
this.compileModulePathConfiguration = createResolvableModuleConfiguration(sourceSet.compileClasspathConfigurationName)
|
||||
compileModulePathConfiguration.extendsFrom(moduleCompileOnly, moduleImplementation)
|
||||
|
||||
this.runtimeModulePathConfiguration = createResolvableModuleConfiguration(sourceSet.runtimeClasspathConfigurationName)
|
||||
runtimeModulePathConfiguration.extendsFrom(moduleRuntimeOnly, moduleImplementation)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds {@code --patch-module} option for the provided module name and the provider of a
|
||||
* folder or JAR file.
|
||||
*
|
||||
* @param moduleName
|
||||
* @param pathProvider
|
||||
*/
|
||||
void patchModule(String moduleName, Provider<Path> pathProvider) {
|
||||
modulePatches.add(Map.entry(moduleName, pathProvider));
|
||||
}
|
||||
|
||||
private FileCollection getCompilationModulePath() {
|
||||
if (mode == Mode.CLASSPATH_ONLY) {
|
||||
return project.files()
|
||||
}
|
||||
return compileModulePathConfiguration - modulePatchOnlyConfiguration
|
||||
}
|
||||
|
||||
private FileCollection getRuntimeModulePath() {
|
||||
if (mode == Mode.CLASSPATH_ONLY) {
|
||||
if (hasModuleDescriptor()) {
|
||||
// The source set is itself a module.
|
||||
throw new GradleException("Source set contains a module but classpath-only" +
|
||||
" dependencies requested: ${project.path}, source set '${sourceSet.name}'")
|
||||
}
|
||||
|
||||
return project.files()
|
||||
}
|
||||
|
||||
return runtimeModulePathConfiguration - modulePatchOnlyConfiguration
|
||||
}
|
||||
|
||||
FileCollection getCompilationClasspath() {
|
||||
if (mode == Mode.CLASSPATH_ONLY) {
|
||||
return sourceSet.compileClasspath
|
||||
}
|
||||
|
||||
// Modify the default classpath by removing anything already placed on module path.
|
||||
// Use a lazy provider to delay computation.
|
||||
project.files({ ->
|
||||
return sourceSet.compileClasspath - compileModulePathConfiguration - modulePatchOnlyConfiguration
|
||||
})
|
||||
}
|
||||
|
||||
CommandLineArgumentProvider getCompilationArguments() {
|
||||
return new CommandLineArgumentProvider() {
|
||||
@Override
|
||||
Iterable<String> asArguments() {
|
||||
FileCollection modulePath = ModularPathsExtension.this.compilationModulePath
|
||||
|
||||
if (modulePath.isEmpty()) {
|
||||
return []
|
||||
}
|
||||
|
||||
ArrayList<String> extraArgs = []
|
||||
extraArgs += ["--module-path", modulePath.join(File.pathSeparator)]
|
||||
|
||||
if (!hasModuleDescriptor()) {
|
||||
// We're compiling what appears to be a non-module source set so we'll
|
||||
// bring everything on module path in the resolution graph,
|
||||
// otherwise modular dependencies wouldn't be part of the resolved module graph and this
|
||||
// would result in class-not-found compilation problems.
|
||||
extraArgs += ["--add-modules", "ALL-MODULE-PATH"]
|
||||
}
|
||||
|
||||
// Add module-patching.
|
||||
extraArgs += getPatchModuleArguments(modulePatches)
|
||||
|
||||
return extraArgs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileCollection getRuntimeClasspath() {
|
||||
if (mode == Mode.CLASSPATH_ONLY) {
|
||||
return sourceSet.runtimeClasspath
|
||||
}
|
||||
|
||||
// Modify the default classpath by removing anything already placed on module path.
|
||||
// Use a lazy provider to delay computation.
|
||||
project.files({ ->
|
||||
return sourceSet.runtimeClasspath - runtimeModulePath - modulePatchOnlyConfiguration
|
||||
})
|
||||
}
|
||||
|
||||
CommandLineArgumentProvider getRuntimeArguments() {
|
||||
return new CommandLineArgumentProvider() {
|
||||
@Override
|
||||
Iterable<String> asArguments() {
|
||||
FileCollection modulePath = ModularPathsExtension.this.runtimeModulePath
|
||||
|
||||
if (modulePath.isEmpty()) {
|
||||
return []
|
||||
}
|
||||
|
||||
def extraArgs = []
|
||||
|
||||
// Add source set outputs to module path.
|
||||
extraArgs += ["--module-path", modulePath.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"]
|
||||
|
||||
// Add module-patching.
|
||||
extraArgs += getPatchModuleArguments(modulePatches)
|
||||
|
||||
return extraArgs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasModuleDescriptor() {
|
||||
|
@ -257,4 +446,86 @@ class ModularPathsExtension {
|
|||
.map(dir -> new File(dir, "module-info.java"))
|
||||
.anyMatch(file -> file.exists())
|
||||
}
|
||||
|
||||
private List<String> getPatchModuleArguments(List<Map.Entry<String, Provider<Path>>> patches) {
|
||||
def args = []
|
||||
patches.each {
|
||||
args.add("--patch-module");
|
||||
args.add(it.key + "=" + it.value.get())
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
private static String toList(FileCollection files) {
|
||||
return files.isEmpty() ? " [empty]" : ("\n " + files.sort().join("\n "))
|
||||
}
|
||||
|
||||
private static String toList(List<Map.Entry<String, Provider<Path>>> patches) {
|
||||
return patches.isEmpty() ? " [empty]" : ("\n " + patches.collect {"${it.key}=${it.value.get()}"}.join("\n "))
|
||||
}
|
||||
|
||||
public void logCompilationPaths(Logger logger) {
|
||||
def value = "Modular extension, compilation paths, source set=${sourceSet.name}${hasModuleDescriptor() ? " (module)" : ""}, mode=${mode}:\n" +
|
||||
" Module path:${toList(compilationModulePath)}\n" +
|
||||
" Class path: ${toList(compilationClasspath)}\n" +
|
||||
" Patches: ${toList(modulePatches)}"
|
||||
|
||||
if (debugPaths) {
|
||||
logger.lifecycle(value)
|
||||
} else {
|
||||
logger.info(value)
|
||||
}
|
||||
}
|
||||
|
||||
public void logRuntimePaths(Logger logger) {
|
||||
def value = "Modular extension, runtime paths, source set=${sourceSet.name}${hasModuleDescriptor() ? " (module)" : ""}, mode=${mode}:\n" +
|
||||
" Module path:${toList(runtimeModulePath)}\n" +
|
||||
" Class path: ${toList(runtimeClasspath)}\n" +
|
||||
" Patches : ${toList(modulePatches)}"
|
||||
|
||||
if (debugPaths) {
|
||||
logger.lifecycle(value)
|
||||
} else {
|
||||
logger.info(value)
|
||||
}
|
||||
}
|
||||
|
||||
public ModularPathsExtension clone() {
|
||||
return (ModularPathsExtension) super.clone()
|
||||
}
|
||||
|
||||
ModularPathsExtension cloneWithMode(Mode newMode) {
|
||||
def cloned = this.clone()
|
||||
cloned.mode = newMode
|
||||
return cloned
|
||||
}
|
||||
|
||||
// Map convention configuration names to "modular" corresponding configurations.
|
||||
static String moduleConfigurationNameFor(String configurationName) {
|
||||
return "module" + configurationName.capitalize().replace("Classpath", "Path")
|
||||
}
|
||||
|
||||
// Create module configuration for the corresponding convention configuration.
|
||||
private Configuration createModuleConfigurationForConvention(String configurationName) {
|
||||
ConfigurationContainer configurations = project.configurations
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide internal dependencies for tasks willing to depend on this modular paths object.
|
||||
*/
|
||||
@Override
|
||||
Iterator<Object> iterator() {
|
||||
return [
|
||||
compileModulePathConfiguration,
|
||||
runtimeModulePathConfiguration
|
||||
].iterator()
|
||||
}
|
||||
}
|
|
@ -38,7 +38,9 @@ configure(rootProject) {
|
|||
// Exclude the parent container project for analysis modules (no artifacts).
|
||||
":lucene:analysis",
|
||||
// Exclude the native module.
|
||||
":lucene:misc:native"
|
||||
":lucene:misc:native",
|
||||
// Exclude test fixtures.
|
||||
":lucene:spatial-test-fixtures"
|
||||
]
|
||||
|
||||
// Exclude all subprojects that are modular test projects and those explicitly
|
||||
|
|
|
@ -33,14 +33,20 @@ configure(rootProject) {
|
|||
def currentJavaVersion = JavaVersion.current()
|
||||
if (currentJavaVersion < minJavaVersion) {
|
||||
throw new GradleException("At least Java ${minJavaVersion} is required, you are running Java ${currentJavaVersion} "
|
||||
+ "[${System.getProperty('java.vm.name')} ${System.getProperty('java.vm.version')}]")
|
||||
+ "[${System.getProperty('java.vm.name')} ${System.getProperty('java.vm.version')}]")
|
||||
}
|
||||
|
||||
// If we're regenerating the wrapper, skip the check.
|
||||
if (!gradle.startParameter.taskNames.contains("wrapper")) {
|
||||
def currentGradleVersion = GradleVersion.current()
|
||||
if (currentGradleVersion != GradleVersion.version(expectedGradleVersion)) {
|
||||
throw new GradleException("Gradle ${expectedGradleVersion} is required (hint: use the gradlew script): this gradle is ${currentGradleVersion}")
|
||||
if (currentGradleVersion.baseVersion == GradleVersion.version(expectedGradleVersion).baseVersion) {
|
||||
logger.warn("Gradle ${expectedGradleVersion} is required but base version of this gradle matches, proceeding (" +
|
||||
"this gradle is ${currentGradleVersion})")
|
||||
} else {
|
||||
throw new GradleException("Gradle ${expectedGradleVersion} is required (hint: use the gradlew script): " +
|
||||
"this gradle is ${currentGradleVersion}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,42 +74,36 @@ allprojects {
|
|||
args += [ "-properties", file("${resources}/ecj.javadocs.prefs").absolutePath ]
|
||||
|
||||
// We depend on modular paths.
|
||||
def modularPaths = sourceSet.modularPaths
|
||||
dependsOn modularPaths.compileModulePathConfiguration
|
||||
def modularPaths = sourceSet.modularPathsForEcj
|
||||
dependsOn modularPaths
|
||||
|
||||
// Add modular dependencies and their transitive dependencies to module path.
|
||||
task.argumentProviders.add(modularPaths.compilationArguments)
|
||||
|
||||
// Add classpath, if needed.
|
||||
task.argumentProviders.add((CommandLineArgumentProvider) {
|
||||
// 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).
|
||||
FileCollection cpath = modularPaths.compilationClasspath.filter { p -> p.exists() }
|
||||
if (!cpath.isEmpty()) {
|
||||
return ["-classpath", cpath.join(File.pathSeparator)]
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
})
|
||||
|
||||
// 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")
|
||||
|
||||
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 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()) {
|
||||
extraArgs += ["-classpath", cpath.join(File.pathSeparator)]
|
||||
}
|
||||
|
||||
extraArgs += ["@" + inputsFile.absolutePath]
|
||||
return extraArgs
|
||||
return ["@" + inputsFile.absolutePath]
|
||||
})
|
||||
|
||||
doFirst {
|
||||
modularPaths.logCompilationPaths(logger)
|
||||
|
||||
tmpDst.mkdirs()
|
||||
|
||||
// escape filename accoring to ECJ's rules:
|
||||
|
@ -118,7 +112,12 @@ allprojects {
|
|||
def escapeFileName = { String s -> s.replaceAll(/ +/, /"$0"/) }
|
||||
inputsFile.setText(
|
||||
srcDirs.collectMany { dir ->
|
||||
project.fileTree(dir: dir, include: "**/*.java" ).files
|
||||
project.fileTree(
|
||||
dir: dir,
|
||||
include: "**/*.java",
|
||||
// Exclude the benchmark class with dependencies on nekohtml, which causes module-classpath conflicts and breaks ecj.
|
||||
exclude: "**/DemoHTMLParser.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:
|
||||
|
|
|
@ -154,12 +154,11 @@ class ValidateSourcePatternsTask extends DefaultTask {
|
|||
(~$/\n\s*var\s+.*=.*<>.*/$) : 'Diamond operators should not be used with var'
|
||||
]
|
||||
|
||||
def found = 0;
|
||||
def violations = new TreeSet();
|
||||
def reportViolation = { f, name ->
|
||||
logger.error('{}: {}', name, f);
|
||||
violations.add(name);
|
||||
found++;
|
||||
String msg = String.format(Locale.ROOT, "%s: %s", f, name)
|
||||
logger.error(msg)
|
||||
violations.add(msg)
|
||||
}
|
||||
|
||||
def javadocsPattern = ~$/(?sm)^\Q/**\E(.*?)\Q*/\E/$;
|
||||
|
@ -258,9 +257,10 @@ class ValidateSourcePatternsTask extends DefaultTask {
|
|||
}
|
||||
progress.completed()
|
||||
|
||||
if (found) {
|
||||
throw new GradleException(String.format(Locale.ENGLISH, 'Found %d violations in source files (%s).',
|
||||
found, violations.join(', ')));
|
||||
if (!violations.isEmpty()) {
|
||||
throw new GradleException(String.format(Locale.ENGLISH, 'Found %d source violation(s):\n %s',
|
||||
violations.size(),
|
||||
violations.join('\n ')))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ description = 'Analyzers for indexing content in different languages and domains
|
|||
|
||||
dependencies {
|
||||
moduleApi project(':lucene:core')
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
||||
// Fetch the data and enable regression tests against woorm/ libreoffice dictionaries.
|
||||
|
|
|
@ -25,5 +25,5 @@ dependencies {
|
|||
|
||||
moduleApi 'com.ibm.icu:icu4j'
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -23,5 +23,5 @@ dependencies {
|
|||
moduleApi project(':lucene:core')
|
||||
moduleApi project(':lucene:analysis:common')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -21,8 +21,5 @@ description = 'Module tests for :lucene:analysis:morfologik'
|
|||
|
||||
dependencies {
|
||||
moduleTestImplementation project(':lucene:analysis:morfologik')
|
||||
moduleTestImplementation("junit:junit", {
|
||||
exclude group: "org.hamcrest"
|
||||
})
|
||||
moduleTestImplementation "org.hamcrest:hamcrest"
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ 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;
|
||||
requires org.apache.lucene.test_framework;
|
||||
|
||||
exports org.apache.lucene.analysis.morfologik.tests;
|
||||
}
|
||||
|
|
|
@ -19,28 +19,24 @@ 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.apache.lucene.tests.util.LuceneTestCase;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestMorfologikAnalyzer {
|
||||
@Test
|
||||
public class TestMorfologikAnalyzer extends LuceneTestCase {
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -27,5 +27,5 @@ dependencies {
|
|||
moduleImplementation 'org.carrot2:morfologik-polish'
|
||||
moduleImplementation 'ua.net.nlp:morfologik-ukrainian-search'
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -23,6 +23,6 @@ dependencies {
|
|||
moduleApi project(':lucene:core')
|
||||
moduleApi project(':lucene:analysis:common')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
||||
|
|
|
@ -24,5 +24,5 @@ dependencies {
|
|||
moduleApi project(':lucene:analysis:common')
|
||||
moduleApi 'org.apache.opennlp:opennlp-tools'
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -25,6 +25,6 @@ dependencies {
|
|||
|
||||
moduleApi 'commons-codec:commons-codec'
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
||||
|
|
|
@ -23,5 +23,5 @@ dependencies {
|
|||
moduleApi project(':lucene:core')
|
||||
moduleApi project(':lucene:analysis:common')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -23,5 +23,5 @@ dependencies {
|
|||
moduleApi project(':lucene:core')
|
||||
moduleApi project(':lucene:analysis:common')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -22,5 +22,5 @@ description = 'Codecs for older versions of Lucene'
|
|||
|
||||
dependencies {
|
||||
moduleApi project(':lucene:core')
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -36,11 +36,18 @@ dependencies {
|
|||
moduleImplementation "org.locationtech.spatial4j:spatial4j"
|
||||
moduleImplementation ("net.sourceforge.nekohtml:nekohtml", {
|
||||
exclude module: "xml-apis"
|
||||
// LUCENE-10337: Exclude xercesImpl from module path because it has split packages with the JDK (!)
|
||||
exclude module: "xercesImpl"
|
||||
})
|
||||
|
||||
// LUCENE-10337: Include xercesImpl on regular classpath where it won't cause conflicts.
|
||||
implementation ("xerces:xercesImpl", {
|
||||
exclude module: "xml-apis"
|
||||
})
|
||||
|
||||
moduleRuntimeOnly project(':lucene:analysis:icu')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
||||
// We add 'conf' to resources because we validate *.alg script correctness in one of the tests.
|
||||
|
|
|
@ -25,7 +25,7 @@ dependencies {
|
|||
moduleImplementation project(':lucene:queries')
|
||||
moduleImplementation project(':lucene:grouping')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
testImplementation project(':lucene:analysis:common')
|
||||
testImplementation project(':lucene:codecs')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:analysis:common')
|
||||
moduleTestImplementation project(':lucene:codecs')
|
||||
}
|
||||
|
|
|
@ -21,5 +21,5 @@ description = 'Lucene codecs and postings formats'
|
|||
|
||||
dependencies {
|
||||
moduleImplementation project(':lucene:core')
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -15,13 +15,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.lucene.codecs.lucene90;
|
||||
package org.apache.lucene.codecs.lucene90.tests;
|
||||
|
||||
/** Test utility class to create mock {@link Lucene90PostingsFormat.IntBlockTermState}. */
|
||||
import org.apache.lucene.codecs.lucene90.Lucene90PostingsFormat.IntBlockTermState;
|
||||
|
||||
/** Test utility class to create mock {@link IntBlockTermState}. */
|
||||
public class MockTermStateFactory {
|
||||
|
||||
/** Creates an empty {@link Lucene90PostingsFormat.IntBlockTermState}. */
|
||||
public static Lucene90PostingsFormat.IntBlockTermState create() {
|
||||
return new Lucene90PostingsFormat.IntBlockTermState();
|
||||
/** Creates an empty {@link IntBlockTermState}. */
|
||||
public static IntBlockTermState create() {
|
||||
return new IntBlockTermState();
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ package org.apache.lucene.codecs.uniformsplit;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import org.apache.lucene.codecs.lucene90.MockTermStateFactory;
|
||||
import org.apache.lucene.codecs.lucene90.tests.MockTermStateFactory;
|
||||
import org.apache.lucene.index.DocValuesType;
|
||||
import org.apache.lucene.index.FieldInfo;
|
||||
import org.apache.lucene.index.IndexOptions;
|
||||
|
|
|
@ -27,7 +27,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import org.apache.lucene.codecs.BlockTermState;
|
||||
import org.apache.lucene.codecs.PostingsReaderBase;
|
||||
import org.apache.lucene.codecs.lucene90.MockTermStateFactory;
|
||||
import org.apache.lucene.codecs.lucene90.tests.MockTermStateFactory;
|
||||
import org.apache.lucene.codecs.uniformsplit.BlockHeader;
|
||||
import org.apache.lucene.codecs.uniformsplit.BlockLine;
|
||||
import org.apache.lucene.codecs.uniformsplit.FSTDictionary;
|
||||
|
|
|
@ -21,8 +21,5 @@ description = 'Module tests for :lucene:core'
|
|||
|
||||
dependencies {
|
||||
moduleTestImplementation project(':lucene:core')
|
||||
moduleTestImplementation("junit:junit", {
|
||||
exclude group: "org.hamcrest"
|
||||
})
|
||||
moduleTestImplementation "org.hamcrest:hamcrest"
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A placeholder module descriptor just so that we can check whether referencing it from the actual
|
||||
* test module works.
|
||||
*/
|
||||
module org.apache.lucene.core.tests.main {
|
||||
exports org.apache.lucene.core.tests.main;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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.core.tests.main;
|
||||
|
||||
/** Just an empty class to reference from the actual tests. */
|
||||
public class EmptyReference {
|
||||
/** No instantiation. */
|
||||
private EmptyReference() {}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** Contains a placeholder class for referencing in tests. */
|
||||
package org.apache.lucene.core.tests.main;
|
|
@ -0,0 +1,26 @@
|
|||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Apache Lucene Core Tests</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>A placeholder module descriptor just so that we can check whether
|
||||
referencing it from the actual test module works.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -19,7 +19,8 @@
|
|||
@SuppressWarnings({"requires-automatic"})
|
||||
module org.apache.lucene.core.tests {
|
||||
requires org.apache.lucene.core;
|
||||
requires junit;
|
||||
requires org.apache.lucene.test_framework;
|
||||
requires org.apache.lucene.core.tests.main;
|
||||
|
||||
exports org.apache.lucene.core.tests;
|
||||
|
||||
|
|
|
@ -17,12 +17,11 @@
|
|||
package org.apache.lucene.core.tests;
|
||||
|
||||
import org.apache.lucene.store.MMapDirectory;
|
||||
import org.apache.lucene.tests.util.LuceneTestCase;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestMMap {
|
||||
@Test
|
||||
public void testUnmapSupported() throws Exception {
|
||||
public class TestMMap extends LuceneTestCase {
|
||||
public void testUnmapSupported() {
|
||||
final Module module = MMapDirectory.class.getModule();
|
||||
Assert.assertTrue("Lucene Core is not loaded as module", module.isNamed());
|
||||
Assert.assertTrue(
|
||||
|
|
|
@ -17,13 +17,12 @@
|
|||
package org.apache.lucene.core.tests;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.apache.lucene.tests.util.LuceneTestCase;
|
||||
import org.apache.lucene.util.ModuleResourceLoader;
|
||||
import org.apache.lucene.util.ResourceLoader;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestModuleResourceLoader extends Assert {
|
||||
public class TestModuleResourceLoader extends LuceneTestCase {
|
||||
private static final Module MODULE = TestModuleResourceLoader.class.getModule();
|
||||
|
||||
private final ResourceLoader loader = new ModuleResourceLoader(MODULE);
|
||||
|
@ -33,7 +32,6 @@ public class TestModuleResourceLoader extends Assert {
|
|||
assertTrue("Test class must be in a named module", MODULE.isNamed());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModuleResources() throws Exception {
|
||||
try (var stream = loader.openResource("org/apache/lucene/core/testresources/accessible.txt")) {
|
||||
stream.available();
|
||||
|
@ -51,8 +49,7 @@ public class TestModuleResourceLoader extends Assert {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModuleClassloading() throws Exception {
|
||||
public void testModuleClassloading() {
|
||||
assertSame(
|
||||
TestModuleResourceLoader.class,
|
||||
loader.findClass(TestModuleResourceLoader.class.getName(), Object.class));
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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.core.tests;
|
||||
|
||||
import org.apache.lucene.core.tests.main.EmptyReference;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.junit.Test;
|
||||
|
||||
/** Intentionally not a subclass of {@code LuceneTestCase}. */
|
||||
public class TestRuntimeDependenciesSane {
|
||||
@Test
|
||||
public void testExternalDependenciesAreModules() {
|
||||
isModule(org.junit.Test.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterProjectDependenciesAreModules() {
|
||||
// The core Lucene should be a modular dependency.
|
||||
isModule(IndexWriter.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTestSourceSetIsAModule() {
|
||||
// The test source set itself should be loaded as a module.
|
||||
isModule(getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMainSourceSetIsAModule() {
|
||||
// The test source set itself should be loaded as a module.
|
||||
isModule(EmptyReference.class);
|
||||
}
|
||||
|
||||
private static void isModule(Class<?> clazz) {
|
||||
var module = clazz.getModule();
|
||||
if (!module.isNamed()) {
|
||||
throw new AssertionError(
|
||||
"Class should be loaded from a named module: "
|
||||
+ clazz.getName()
|
||||
+ " but is instead part of: "
|
||||
+ module);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,6 +20,6 @@ apply plugin: 'java-library'
|
|||
description = 'Lucene core library'
|
||||
|
||||
dependencies {
|
||||
testImplementation project(':lucene:codecs')
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:codecs')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -27,5 +27,5 @@ dependencies {
|
|||
moduleImplementation project(':lucene:queryparser')
|
||||
moduleImplementation project(':lucene:expressions')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -29,5 +29,5 @@ dependencies {
|
|||
moduleImplementation 'org.ow2.asm:asm'
|
||||
moduleImplementation 'org.ow2.asm:asm-commons'
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -22,11 +22,10 @@ description = 'Faceted indexing and search capabilities'
|
|||
|
||||
dependencies {
|
||||
moduleApi project(':lucene:core')
|
||||
|
||||
moduleImplementation 'com.carrotsearch:hppc'
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
testImplementation project(':lucene:queries')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:queries')
|
||||
// Required for opening older indexes for backward compatibility tests
|
||||
testImplementation project(':lucene:backward-codecs')
|
||||
moduleTestImplementation project(':lucene:backward-codecs')
|
||||
}
|
||||
|
|
|
@ -25,5 +25,5 @@ dependencies {
|
|||
|
||||
moduleImplementation project(':lucene:queries')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ dependencies {
|
|||
moduleImplementation project(':lucene:queries')
|
||||
moduleImplementation project(':lucene:memory')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
testImplementation project(':lucene:analysis:common')
|
||||
testImplementation project(':lucene:queryparser')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:analysis:common')
|
||||
moduleTestImplementation project(':lucene:queryparser')
|
||||
}
|
||||
|
|
|
@ -21,5 +21,5 @@ description = 'Index-time and Query-time joins for normalized content'
|
|||
|
||||
dependencies {
|
||||
moduleApi project(':lucene:core')
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
|
@ -45,7 +45,7 @@ dependencies {
|
|||
moduleImplementation project(':lucene:analysis:stempel')
|
||||
moduleImplementation project(':lucene:suggest')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
||||
// Configure main class name for all JARs.
|
||||
|
|
|
@ -23,6 +23,6 @@ description = 'Single-document in-memory index implementation'
|
|||
dependencies {
|
||||
moduleApi project(':lucene:core')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
testImplementation project(':lucene:queryparser')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:queryparser')
|
||||
}
|
|
@ -21,7 +21,7 @@ description = 'Index tools and other miscellaneous code'
|
|||
|
||||
dependencies {
|
||||
moduleApi project(':lucene:core')
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
|
||||
nativeDeps project(":lucene:misc:native")
|
||||
}
|
|
@ -25,6 +25,6 @@ dependencies {
|
|||
moduleImplementation project(':lucene:memory')
|
||||
moduleImplementation project(':lucene:analysis:common')
|
||||
|
||||
testImplementation project(':lucene:queryparser')
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:queryparser')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ description = 'Filters and Queries that add to core Lucene'
|
|||
dependencies {
|
||||
moduleApi project(':lucene:core')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
testImplementation project(':lucene:expressions')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:expressions')
|
||||
}
|
||||
|
||||
|
|
|
@ -24,5 +24,5 @@ dependencies {
|
|||
moduleApi project(':lucene:queries')
|
||||
moduleApi project(':lucene:sandbox')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -30,12 +30,12 @@ dependencies {
|
|||
|
||||
moduleImplementation 'javax.servlet:javax.servlet-api'
|
||||
|
||||
testImplementation 'org.eclipse.jetty:jetty-server'
|
||||
testImplementation('org.eclipse.jetty:jetty-servlet', {
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
|
||||
moduleTestImplementation 'org.eclipse.jetty:jetty-server'
|
||||
moduleTestImplementation('org.eclipse.jetty:jetty-servlet', {
|
||||
exclude group: "org.eclipse.jetty", module: "jetty-security"
|
||||
})
|
||||
testImplementation 'org.eclipse.jetty:jetty-continuation'
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation 'org.eclipse.jetty:jetty-continuation'
|
||||
}
|
||||
|
||||
|
|
|
@ -22,5 +22,5 @@ description = 'Various third party contributions and new ideas'
|
|||
dependencies {
|
||||
moduleApi project(':lucene:core')
|
||||
moduleApi project(':lucene:queries')
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -19,6 +19,10 @@ apply plugin: 'java-library'
|
|||
|
||||
description = 'Geospatial search'
|
||||
|
||||
configurations {
|
||||
spatial4jTestPatch
|
||||
}
|
||||
|
||||
dependencies {
|
||||
moduleApi project(':lucene:core')
|
||||
moduleApi project(':lucene:spatial3d')
|
||||
|
@ -26,11 +30,17 @@ dependencies {
|
|||
moduleApi 'org.locationtech.spatial4j:spatial4j'
|
||||
moduleApi 'io.sgr:s2-geometry-library-java'
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
testImplementation testFixtures(project(':lucene:spatial3d'))
|
||||
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:spatial-test-fixtures')
|
||||
moduleTestImplementation 'org.locationtech.jts:jts-core'
|
||||
testImplementation 'org.locationtech.spatial4j:spatial4j::tests'
|
||||
|
||||
// We add patched modules to this configuration because otherwise IDEs would not see the
|
||||
// dependency at all, even in classpath mode (they don't see --patch-module commands we
|
||||
// add to the compiler and test tasks).
|
||||
moduleTestPatchOnly 'org.locationtech.spatial4j:spatial4j::tests'
|
||||
spatial4jTestPatch 'org.locationtech.spatial4j:spatial4j::tests'
|
||||
}
|
||||
|
||||
|
||||
sourceSets.test.extensions.configure("modularPaths", {
|
||||
it.patchModule("spatial4j", project.providers.provider({ configurations.spatial4jTestPatch.singleFile }))
|
||||
})
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
package org.apache.lucene.spatial.spatial4j;
|
||||
|
||||
import static org.apache.lucene.spatial3d.geom.RandomGeo3dShapeGenerator.*;
|
||||
import static org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator.*;
|
||||
import static org.locationtech.spatial4j.distance.DistanceUtils.DEGREES_TO_RADIANS;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
apply plugin: 'java-library'
|
||||
|
||||
description = '3D spatial planar geometry test fixtures'
|
||||
|
||||
dependencies {
|
||||
moduleImplementation project(':lucene:test-framework')
|
||||
moduleImplementation project(':lucene:spatial3d')
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.lucene.spatial3d.geom;
|
||||
package org.apache.lucene.spatial3d.tests;
|
||||
|
||||
import com.carrotsearch.randomizedtesting.RandomizedContext;
|
||||
import com.carrotsearch.randomizedtesting.RandomizedTest;
|
||||
|
@ -25,6 +25,23 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import org.apache.lucene.spatial3d.geom.GeoArea;
|
||||
import org.apache.lucene.spatial3d.geom.GeoAreaShape;
|
||||
import org.apache.lucene.spatial3d.geom.GeoBBox;
|
||||
import org.apache.lucene.spatial3d.geom.GeoBBoxFactory;
|
||||
import org.apache.lucene.spatial3d.geom.GeoCircle;
|
||||
import org.apache.lucene.spatial3d.geom.GeoCircleFactory;
|
||||
import org.apache.lucene.spatial3d.geom.GeoCompositeAreaShape;
|
||||
import org.apache.lucene.spatial3d.geom.GeoCompositeMembershipShape;
|
||||
import org.apache.lucene.spatial3d.geom.GeoPath;
|
||||
import org.apache.lucene.spatial3d.geom.GeoPathFactory;
|
||||
import org.apache.lucene.spatial3d.geom.GeoPoint;
|
||||
import org.apache.lucene.spatial3d.geom.GeoPointShape;
|
||||
import org.apache.lucene.spatial3d.geom.GeoPointShapeFactory;
|
||||
import org.apache.lucene.spatial3d.geom.GeoPolygon;
|
||||
import org.apache.lucene.spatial3d.geom.GeoPolygonFactory;
|
||||
import org.apache.lucene.spatial3d.geom.GeoShape;
|
||||
import org.apache.lucene.spatial3d.geom.PlanetModel;
|
||||
|
||||
/**
|
||||
* Class for generating random Geo3dShapes. They can be generated under given constraints which are
|
||||
|
@ -42,22 +59,22 @@ public final class RandomGeo3dShapeGenerator {
|
|||
private static final int MAX_POINT_ITERATIONS = 1000;
|
||||
|
||||
/* Supported shapes */
|
||||
protected static final int CONVEX_POLYGON = 0;
|
||||
protected static final int CONVEX_POLYGON_WITH_HOLES = 1;
|
||||
protected static final int CONCAVE_POLYGON = 2;
|
||||
protected static final int CONCAVE_POLYGON_WITH_HOLES = 3;
|
||||
protected static final int COMPLEX_POLYGON = 4;
|
||||
protected static final int CIRCLE = 5;
|
||||
protected static final int RECTANGLE = 6;
|
||||
protected static final int PATH = 7;
|
||||
protected static final int COLLECTION = 8;
|
||||
protected static final int POINT = 9;
|
||||
protected static final int LINE = 10;
|
||||
protected static final int EXACT_CIRCLE = 11;
|
||||
public static final int CONVEX_POLYGON = 0;
|
||||
public static final int CONVEX_POLYGON_WITH_HOLES = 1;
|
||||
public static final int CONCAVE_POLYGON = 2;
|
||||
public static final int CONCAVE_POLYGON_WITH_HOLES = 3;
|
||||
public static final int COMPLEX_POLYGON = 4;
|
||||
public static final int CIRCLE = 5;
|
||||
public static final int RECTANGLE = 6;
|
||||
public static final int PATH = 7;
|
||||
public static final int COLLECTION = 8;
|
||||
public static final int POINT = 9;
|
||||
public static final int LINE = 10;
|
||||
public static final int EXACT_CIRCLE = 11;
|
||||
|
||||
/* Helper shapes for generating constraints whch are just three sided polygons */
|
||||
protected static final int CONVEX_SIMPLE_POLYGON = 500;
|
||||
protected static final int CONCAVE_SIMPLE_POLYGON = 501;
|
||||
public static final int CONVEX_SIMPLE_POLYGON = 500;
|
||||
public static final int CONCAVE_SIMPLE_POLYGON = 501;
|
||||
|
||||
/** Static methods only. */
|
||||
private RandomGeo3dShapeGenerator() {}
|
||||
|
@ -550,7 +567,7 @@ public final class RandomGeo3dShapeGenerator {
|
|||
collection.addShape(member);
|
||||
}
|
||||
}
|
||||
if (collection.shapes.size() == 0) {
|
||||
if (collection.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
return collection;
|
||||
|
@ -963,7 +980,7 @@ public final class RandomGeo3dShapeGenerator {
|
|||
* @param points The points to order.
|
||||
* @return The list of ordered points anti-clockwise.
|
||||
*/
|
||||
protected static List<GeoPoint> orderPoints(List<GeoPoint> points) {
|
||||
public static List<GeoPoint> orderPoints(List<GeoPoint> points) {
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
double z = 0;
|
||||
|
@ -1005,8 +1022,7 @@ public final class RandomGeo3dShapeGenerator {
|
|||
* Class that holds the constraints that are given to build shapes. It consists in a list of
|
||||
* GeoAreaShapes and relationships the new shape needs to satisfy.
|
||||
*/
|
||||
static class Constraints extends HashMap<GeoAreaShape, Integer> {
|
||||
|
||||
public static class Constraints extends HashMap<GeoAreaShape, Integer> {
|
||||
/**
|
||||
* Check if the shape is valid under the constraints.
|
||||
*
|
||||
|
@ -1052,7 +1068,7 @@ public final class RandomGeo3dShapeGenerator {
|
|||
// For GeoCompositeMembershipShape we only consider the first shape to help
|
||||
// converging
|
||||
if (relationship == GeoArea.WITHIN && shape instanceof GeoCompositeMembershipShape) {
|
||||
shape = (((GeoCompositeMembershipShape) shape).shapes.get(0));
|
||||
shape = (((GeoCompositeMembershipShape) shape).getShapes().get(0));
|
||||
}
|
||||
switch (relationship) {
|
||||
case GeoArea.DISJOINT:
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** Shared test fixtures for spatial packages. */
|
||||
package org.apache.lucene.spatial3d.tests;
|
|
@ -0,0 +1,24 @@
|
|||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Apache Lucene Spatial Test Fixtures Module</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Internal test fixtures for spatial modules</h1>
|
||||
</body>
|
||||
</html>
|
|
@ -16,13 +16,17 @@
|
|||
*/
|
||||
|
||||
apply plugin: 'java-library'
|
||||
apply plugin: 'java-test-fixtures'
|
||||
|
||||
description = '3D spatial planar geometry APIs'
|
||||
|
||||
dependencies {
|
||||
moduleApi project(':lucene:core')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
|
||||
testFixturesApi project(':lucene:test-framework')
|
||||
testImplementation project(':lucene:test-framework')
|
||||
// We have to exclude ourselves because spatial-test-fixtures depend
|
||||
// on the main source set of this project and tests would receive the
|
||||
// dependency twice - on classpath and in module path.
|
||||
moduleTestImplementation(project(':lucene:spatial-test-fixtures'), {
|
||||
exclude module: "spatial3d"
|
||||
})
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.io.InputStream;
|
|||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -149,4 +150,9 @@ public abstract class GeoBaseCompositeShape<T extends GeoShape> extends BasePlan
|
|||
GeoBaseCompositeShape<?> other = (GeoBaseCompositeShape<?>) o;
|
||||
return super.equals(other) && shapes.equals(other.shapes);
|
||||
}
|
||||
|
||||
/** Returns an unmodifiable list of composed shapes. */
|
||||
public List<T> getShapes() {
|
||||
return Collections.unmodifiableList(shapes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
|
||||
package org.apache.lucene.spatial3d.geom;
|
||||
|
||||
import static org.apache.lucene.spatial3d.geom.RandomGeo3dShapeGenerator.*;
|
||||
import static org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator.*;
|
||||
|
||||
import com.carrotsearch.randomizedtesting.annotations.Repeat;
|
||||
import org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator;
|
||||
import org.apache.lucene.tests.util.LuceneTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
package org.apache.lucene.spatial3d.geom;
|
||||
|
||||
import static org.apache.lucene.spatial3d.geom.RandomGeo3dShapeGenerator.*;
|
||||
import static org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator.*;
|
||||
|
||||
import com.carrotsearch.randomizedtesting.annotations.Repeat;
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
package org.apache.lucene.spatial3d.geom;
|
||||
|
||||
import static org.apache.lucene.spatial3d.geom.RandomGeo3dShapeGenerator.*;
|
||||
import static org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator.*;
|
||||
|
||||
import com.carrotsearch.randomizedtesting.generators.BiasedNumbers;
|
||||
import java.util.ArrayList;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
package org.apache.lucene.spatial3d.geom;
|
||||
|
||||
import static org.apache.lucene.spatial3d.geom.RandomGeo3dShapeGenerator.*;
|
||||
import static org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator.*;
|
||||
|
||||
import org.apache.lucene.tests.util.LuceneTestCase;
|
||||
import org.junit.Test;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
package org.apache.lucene.spatial3d.geom;
|
||||
|
||||
import static org.apache.lucene.spatial3d.geom.RandomGeo3dShapeGenerator.*;
|
||||
import static org.apache.lucene.spatial3d.tests.RandomGeo3dShapeGenerator.*;
|
||||
|
||||
import com.carrotsearch.randomizedtesting.annotations.Repeat;
|
||||
import java.util.ArrayList;
|
||||
|
|
|
@ -23,5 +23,5 @@ dependencies {
|
|||
moduleApi project(':lucene:core')
|
||||
moduleApi project(':lucene:analysis:common')
|
||||
|
||||
testImplementation project(':lucene:test-framework')
|
||||
moduleTestImplementation project(':lucene:test-framework')
|
||||
}
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
*/
|
||||
|
||||
/** Lucene test framework. */
|
||||
@SuppressWarnings({"module", "requires-automatic"})
|
||||
@SuppressWarnings({"module", "requires-automatic", "requires-transitive-automatic"})
|
||||
module org.apache.lucene.test_framework {
|
||||
requires org.apache.lucene.core;
|
||||
requires org.apache.lucene.codecs;
|
||||
requires junit;
|
||||
requires randomizedtesting.runner;
|
||||
requires transitive junit;
|
||||
requires transitive randomizedtesting.runner;
|
||||
|
||||
exports org.apache.lucene.tests.analysis.standard;
|
||||
exports org.apache.lucene.tests.analysis;
|
||||
|
|
|
@ -63,5 +63,6 @@ include "lucene:replicator"
|
|||
include "lucene:sandbox"
|
||||
include "lucene:spatial3d"
|
||||
include "lucene:spatial-extras"
|
||||
include "lucene:spatial-test-fixtures"
|
||||
include "lucene:suggest"
|
||||
include "lucene:test-framework"
|
||||
|
|
|
@ -23,7 +23,7 @@ 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)
|
||||
xerces:xercesImpl:2.12.0 (1 constraints: 3705353b)
|
||||
|
||||
[Test dependencies]
|
||||
org.assertj:assertj-core:3.21.0 (1 constraints: 38053c3b)
|
||||
|
|
Loading…
Reference in New Issue