You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Apache POI导出Excel时遇日志依赖冲突及类缺失问题求助

问题:Apache POI导出Excel时的日志依赖冲突与缺失错误

我手动添加JAR包使用Apache POI导出应用信息到Excel时,出现两个关键错误:

  • ERROR StatusLogger Unable to create class org.apache.logging.log4j.tojul.JULLoggerContextFactory specified in provider URL null
  • 后续触发NoClassDefFoundError: org/slf4j/Logger异常

我没有使用Maven,请求帮忙解决该问题。

相关代码

import facilities.Facility;
import facilities.Toilet;
import facilities.buildings.Building;
import facilities.buildings.Cafe;
import facilities.buildings.Hall;
import facilities.buildings.Lab;
import facilities.buildings.Library;
import facilities.buildings.Theatre;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Random;
import java.util.Scanner;
import university.Estate;
import university.Staff;
import university.University;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public void retrieveInfo() throws Exception{
    boolean endRetrieve = false;
    while (!endRetrieve) {
        System.out.println("Select the information you want to retrieve");
        System.out.println("[1] Facility information");
        System.out.println("[2] Staff information");
        System.out.println("[3] End Retrieve Information");
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter number");
        String choice = sc.next();
        if (Integer.parseInt(choice) == 1) {
            int i = 1;
            System.out.println("Choose the facility you would like to retrieve");
            for (Facility fa2 : university.getEstateObject().getFacilities()) {
                System.out.println("[" + i + "] " + fa2.getName());
                i++;
            }
            System.out.println("Enter number or press 'E' to export facilities data to txt file");
            String facilityChoice = sc.next();
            if (facilityChoice.equals("E")) {
                exportFacilitySpreadsheet();
            }else if (Integer.parseInt(facilityChoice) - 1 >= university.getEstateObject()
                    .getFacilities().length) {
                if (university.getEstateObject().getFacilities()[Integer.parseInt(facilityChoice)-1] instanceof Toilet){
                    System.out.println("Name: " + university.getEstateObject().getFacilities()[Integer.parseInt(facilityChoice)-1].getName());
                    System.out.println("Type: Toilet");
                }else{
                    Building b1 =
                        (Building)
                            university.getEstateObject().getFacilities()[Integer.parseInt(facilityChoice) - 1];
                    System.out.println(
                        "Name: "
                            + university
                            .getEstateObject()
                            .getFacilities()[Integer.parseInt(facilityChoice) - 1]
                            .getName());
                    String type = null;
                    if (b1 instanceof Hall){
                        type = "Hall";
                    }else if(b1 instanceof Lab){
                        type = "Lab";
                    }else if(b1 instanceof Theatre){
                        type = "Theatre";
                    }else if(b1 instanceof Library){
                        type = "Library";
                    }else if (b1 instanceof Cafe){
                        type = "Cafe";
                    }
                    System.out.println("Type: " + type);
                    System.out.println("Number of Level: " + b1.getLevel());
                    System.out.println("Max level reach: " + b1.maxLevelReached());
                    System.out.println("Capacity: " + b1.getCapacity());
                    if (b1 instanceof Library) {
                        System.out.println(
                            "Number of books: "
                                + ((Library) b1)
                                .getNumberOfBooks()); // printing number of books only if it's a library
                    }
                }
            }else {
                System.out.println("Error input");
            }
        }
    }
}

完整错误信息

ERROR StatusLogger Unable to create class org.apache.logging.log4j.tojul.JULLoggerContextFactory specified in provider URL null
 java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    at org.apache.logging.log4j.util.LoaderUtil.newInstanceOf(LoaderUtil.java:254)
    at org.apache.logging.log4j.LogManager.<clinit>(LogManager.java:94)
    at org.apache.poi.ooxml.POIXMLDocumentPart.<clinit>(POIXMLDocumentPart.java:56)
    at EcsSim.exportFacilitySpreadsheet(EcsSim.java:633)
    at EcsSim.retrieveInfo(EcsSim.java:542)
    at EcsSim.main(EcsSim.java:683)
Caused by: java.lang.IllegalStateException: log4j-jul JAR is mutually exclusive with the log4j-to-jul JAR(the first routes calls from Log4j to JUL, the second from Log4j to JUL)
    at org.apache.logging.log4j.tojul.JULLoggerContextFactory.<init>(JULLoggerContextFactory.java:46)
    ... 11 more
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/Logger
    at org.apache.logging.slf4j.SLF4JLoggerContext.getLogger(SLF4JLoggerContext.java:41)
    at org.apache.logging.log4j.spi.LoggerContext.getLogger(LoggerContext.java:46)
    at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:611)
    at org.apache.poi.ooxml.POIXMLDocumentPart.<clinit>(POIXMLDocumentPart.java:56)
    at EcsSim.exportFacilitySpreadsheet(EcsSim.java:633)
    at EcsSim.retrieveInfo(EcsSim.java:542)
    at EcsSim.main(EcsSim.java:683)
Caused by: java.lang.ClassNotFoundException: org.slf4j.Logger
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    ... 7 more

当前添加的JAR包

我引入的JAR包含Apache POI系列的poi-4.1.2.jar、poi-ooxml-4.1.2.jar、poi-ooxml-schemas-4.1.2.jar,以及log4j-core-2.17.1.jar、log4j-jul-2.17.1.jar等日志相关文件。


解决方案

1. 移除冲突的日志JAR包

错误明确提示log4j-jul和log4j-to-jul是互斥的,二者功能都是实现日志桥接但方向冲突,直接删除其中一个(推荐删除log4j-to-jul相关JAR)。

2. 补充缺失的SLF4J依赖

NoClassDefFoundError说明缺少SLF4J核心类,需要添加两个必要JAR:

  • slf4j-api-1.7.36.jar(版本与你的Log4j版本兼容即可)
  • log4j-slf4j-impl-2.17.1.jar(用于将SLF4J的日志请求桥接到Log4j)

3. 补全POI的必备依赖

除已有的POI包外,还需添加以下依赖包避免其他类缺失:

  • commons-codec-1.15.jar
  • commons-collections4-4.4.jar
  • commons-math3-3.6.1.jar
  • curvesapi-1.06.jar
  • xmlbeans-3.1.0.jar

4. 验证与重启

添加完所有包后,清理项目编译缓存,重新运行导出代码,确认日志类加载正常,Excel导出功能可正常使用。


内容的提问来源于stack exchange,提问作者yyxxyyxx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 16:00:56