Skip to content
Advertisement

Lucene split package: module reads package ‘org.apache.lucene.analysis.standard’ from both ‘lucene.analyzers.common’ and ‘lucene.core’

Given my module-info.java:

module my_module {
    requires lucene.analyzers.common;
    requires lucene.core;
}

I get the following error:

Module ‘my_module’ reads package ‘org.apache.lucene.analysis.standard’ from both ‘lucene.analyzers.common’ and ‘lucene.core’

In my code I use the following imports:

// import from lucene.analyzers.common
import org.apache.lucene.analysis.util.TokenizerFactory;
// import from lucene.core
import org.apache.lucene.analysis.TokenStream;

How can resolve this split package problem?

Advertisement

Answer

As you may already know, Lucene doesn’t support the Java Platform Module System properly, so it doesn’t define modules and contains split packages, which don’t work well with the module system.

However, there is a workaround that allows using Lucene in JPMS projects. The exact way to implement it depends on your particular build enviroment, and I don’t know how yours is set up, but nevertheless the basic idea is the same for any build environment. The Lucene migration guide provides the first clue (emphasis mine):

If you are migrating your project to Java 9 Jigsaw module system, keep in mind that Lucene currently does not yet support module-info.java declarations of service provider impls (provides statement). It is therefore recommended to keep all of Lucene in one Uber-Module and not try to split Lucene into several modules. As soon as Lucene will migrate to Java 9 as minimum requirement, we will work on improving that.

Keeping all Lucene in a single module (“Uber-Module”) means combining all Lucene JARs in a single JAR, so the default Java behaviour of assigning a automatic module to that uber JAR just works, because the uber JAR contains the split packages merged. As a quick and dirty solution, you can set up a shell script to merge the Lucene JARs in one before building, but integrating that step in your build process is a better idea.

For instance, to do that in Maven, you should first create a Maven module inside your Maven project, so the module has your Maven project as its parent. With that done, the dependencies and shade plugin of the created module must be configured so that the resulting JAR contains all of the Lucene libraries you use. Then you declare that Maven module as a dependency inside your project. For more detailed instructions and discussion, see https://www.reddit.com/r/javahelp/comments/8v914c/using_nonmodule_library_lucene_in_java_10_project/, https://lists.apache.org/thread/ydrdwx63t80n7hsbz51467lp9z8w75tk and Shading a dependency in Maven.

Advertisement