Search code examples
javaimportandroid-gradle-pluginapache-poidocx

Gradle Duplicate Class Error Implementing Apache POI Dependencies


I am having trouble to properly import the Apache POI dependencies I need to run in my Java program. I do need to use some classes to manipulate a .docx file in my program. Since I am doing it in Android Studio, I am importing all the dependencies I need through gradle. However, I am facing some trouble during those imports.

Since I am manipulating some lists in my Word/docx file, I need to use the CTLevelSuffix and STLevelSuffix classes. However, if I implement just org.apache.poi:poi-ooxml:5.2.3, those classes cannot be found.

So, I thought that I should use the org.apache.poi:poi-ooxml-full:5.2.3 implementation. However, if I do so, those 2 classes can be imported, however, all the org.apache.poi.xwpf.usermodel.* classes are not imported.

//These imports do not work if I only use "implementation 'org.apache.poi:poi-ooxml-full:5.2.3' "
import org.apache.poi.xwpf.usermodel.XWPFAbstractNum;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFNumbering;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
//----------------------------
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLvl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STNumberFormat;
//-----------------------------------
//These imports do not work if I only use " implementation 'org.apache.poi:poi-ooxml:5.2.3' "
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLevelSuffix;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLevelSuffix;

Then, I thought that my problems would be solved if I implemented both poi-ooxml and poi-ooxml-full. However, if I do so, I get plenty of building errors, which a small amount of them will be shown here:

...
Duplicate class org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual found in modules jetified-poi-ooxml-full-5.2.3 (org.apache.poi:poi-ooxml-full:5.2.3) and jetified-poi-ooxml-lite-5.2.3 (org.apache.poi:poi-ooxml-lite:5.2.3)
Duplicate class org.openxmlformats.schemas.presentationml.x2006.main.CTHandoutMasterIdList found in modules jetified-poi-ooxml-full-5.2.3 (org.apache.poi:poi-ooxml-full:5.2.3) and jetified-poi-ooxml-lite-5.2.3 (org.apache.poi:poi-ooxml-lite:5.2.3)
Duplicate class org.openxmlformats.schemas.presentationml.x2006.main.CTHandoutMasterIdListEntry found in modules jetified-poi-ooxml-full-5.2.3 (org.apache.poi:poi-ooxml-full:5.2.3) and jetified-poi-ooxml-lite-5.2.3 (org.apache.poi:poi-ooxml-lite:5.2.3)
...

I get that both poi-ooxml and poi-ooxml-full have the same classes and that's why the building keeps failing. However, I do not know how to fix this error since I wasn't able to find a way to import the classes that I need.

Can someone help?

By the way, the implementation snippet of my build.gradle(:app) file looks like that:

...
dependencies {

...
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    implementation 'com.github.bumptech.glide:glide:4.13.1'
    implementation 'com.github.Gavras:MultiLineRadioGroup:v1.0.0.6'
    implementation 'org.apache.poi:poi-ooxml-full:5.2.3'
    implementation 'org.apache.poi:poi-ooxml:5.2.3'
...

}

Solution

  • After a while pondering about this problem, I ended up figuring out that such error was more a "gradle"-based one than an Apache POI one.

    Apache POI Component Usage

    As defined in the Apache POI Component Overview, you might have to use more than one jar dependency to fulfill your needs. In my case, since I needed some OpenXML4J components, I had to use both poi-ooxml and poi-ooxml-full jars in order to have access to everything I needed. However, since these two jar have a lot of classes in common, that ended up creating the "duplicate error" problem I was facing.

    If we look closer to one (of the many) error messages I got during my building process, we can see which modules were causing my problem:

    ...
    Duplicate class (...) found in
    modules jetified-poi-ooxml-full-5.2.3 (org.apache.poi:poi-ooxml-full:5.2.3) 
    and jetified-poi-ooxml-lite-5.2.3 (org.apache.poi:poi-ooxml-lite:5.2.3)
    ...
    

    However, a closer look into my gradle file (which the important snippets of it are shown below) would demonstrate that I did not add the poi-ooxml-lite jar, only the poi-ooxml (and poi-ooxml-full). But, as defined on the Component Overview:

    poi-ooxml requires poi-ooxml-lite

    Which means that, in order to use the former you have to add the latter. However, since gradle helps automatize the download of the dependencies, adding poi-ooxml makes the builder download all the requirements for this jar to work.

    Duplicate Class Problem

    Since the poi-ooxml-full (formerly known as ooxml-schemas) is only recommended if you need some features not fully implemented in poi-ooxml, normally you would not have the need to use both jars. However, if you DO need them (like me), you will end up incorring in the problem of this question. That's because, as said before, poi-ooxml requires poi-ooxml-lite to work (and, therefore, is downloaded by gradle when you build your project) but plenty of the classes present in the lite version are ALSO present in the full version.

    So, in order to solve the problem of duplicate classes, I used the gradle configuration and defined the exclusion of the poi-ooxml-lite module, since all classes inside it are present inside the poi-ooxml-full module as well.

    My build.gradle(:app) file looks like this

    plugins {
        id 'com.android.application'
    }
    
    android {
        ...
        defaultConfig {
         ...
        }
    
        ...
        configurations {
            all {
                exclude group: 'org.apache.poi', module: 'poi-ooxml-lite'
            }
        }
    }
    
    dependencies {
    ...
        implementation 'org.apache.poi:poi-ooxml:5.2.3'
        implementation 'org.apache.poi:poi-ooxml-full:5.2.3'
    ...
    }
    

    That being said, Apache POI surely could have made a more intuitive guide or FAQ for some of their modules. The fact that, even if you implement poi-ooxml module you still might need to implement the poi-ooxml-lite or poi-ooxml-full modules are totally counter intuitive at best.