0

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'
...

}
CorMatt
  • 97
  • 1
  • 9
  • 2
    Java on droid isn't quite the same as standard Java sdk... I would check this github: https://github.com/centic9/poi-on-android The author talks about the XML parser issue. – pcalkins Nov 08 '22 at 23:36
  • 2
    See also the _Component Map_ note cited [here](https://stackoverflow.com/a/72839258/230513). – trashgod Nov 08 '22 at 23:43
  • @pcalkins so, the thing is: I am not having trouble with the XML parser if I use the `poi-ooxml:5.2.3` jar. The issue is that I need to get the `CTLevelSuffix` and `STLevelSuffix` classes that seem to be available only in `poi-ooxml-full:5.2.3` but, if I do put both dependencies in my gradle, I cannot compile because Gradle/AndroidStudio accuses the existence of duplicated classes. However, since I am inexperienced in such things, perhaps I did not understand your message about the XML parser...? – CorMatt Nov 09 '22 at 16:55
  • @trashgod I did look up this _Component Map_, and it was from there that I got the idea of adding both `poi-ooxml:5.2.3` and `poi-ooxml-full:5.2.3` dependencies in my gradle file. The problem is the fact that, if I do so, the build of my app fails because of the duplicate classes present in both jars, just like the examples I showed in my question. Is there a way to avoid those building errors while using both dependencies? – CorMatt Nov 09 '22 at 17:01
  • I would import the jars manually following the github project... (or start from a clone of it) – pcalkins Nov 09 '22 at 17:37

1 Answers1

1

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.

CorMatt
  • 97
  • 1
  • 9
  • @trashgod I got confused as well for the same reason. The thing is: I needed `poi-ooxml` because that gave me the XWPF classes to deal with the .docx file. I needed `poi-ooxml-full` because I needed some accessory classes to define some variables. The thing is that, since there were a lot of overlapping classes in both modules, gradle had a hard time building the project. If you take a look into the "error" section of my question, the problems was the existence of duplicate classes in `jetified-poi-ooxml-full` and `jetified-poi-ooxml-lite` modules (the last one being part of the `poi-ooxml`) – CorMatt Nov 09 '22 at 20:54
  • @trashgod So, since adding a `poi-ooxml-full` was necessary in order to obtain those classes; and all the classes present in `poi-ooxml-lite` could also be found in `poi-ooxml-full`, it was only a matter of excluding the usage of the lite-classes during building time because they could also be found inside another dependency that I had to use on my project anyway – CorMatt Nov 09 '22 at 20:57
  • @trashgod Also, by _Component Map_ indication, I did use `poi-ooxml` plus `poi-ooxml-full`. I just "canceled out" the poi-ooxml-lite parts that could be found inside poi-ooxml, and let the classes in poi-ooxml-full to be used – CorMatt Nov 09 '22 at 21:00
  • @trashgod I can cite the _Component Map_, sure, but I am not sure if that would be useful... I mean, I got the building error _because_ I followed the Component Map, implementing the `poi-ooxml` jars as intended. The thing is that, at least for gradle, that was bad because they have overlapping/duplicate classes – CorMatt Nov 10 '22 at 16:15
  • @trashgod I did edit my answer and cited the _Component Map_ now. Do you think it is a better/acceptable answer now? – CorMatt Nov 10 '22 at 17:09