'program is packaged into an EXE include log4j2, an error occurs when the EXE software is run
Since POI relies on log4j 2.7.1, log4J-core and log4J-API have been added to Maven. There are no errors when the program is packaged as a JAR. An error occurs when using Exe4J to package the JAR into an EXE. . At first, I thought the log4j.xml configuration file didn't cause it, but it still didn't work when I put log4j.xml in the Resource folder. The development environment used is Win10 + ECplise 2022-03+ JDK17. Here is the error code:
WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance.
java.lang.NoClassDefFoundError: javax/naming/Context
at org.apache.logging.log4j.core.lookup.Interpolator.<init>(Interpolator.java:113)
at org.apache.logging.log4j.core.config.AbstractConfiguration.<init>(AbstractConfiguration.java:133)
at org.apache.logging.log4j.core.config.NullConfiguration.<init>(NullConfiguration.java:32)
at org.apache.logging.log4j.core.LoggerContext.<clinit>(LoggerContext.java:85)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.createContext(ClassLoaderContextSelector.java:254)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getDefault(ClassLoaderContextSelector.java:266)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:146)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:123)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:230)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:47)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:176)
at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:54)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:47)
at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:33)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:285)
at poitest.test.<clinit>(test.java:16)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at com.exe4j.runtime.LauncherEngine.launch(LauncherEngine.java:84)
at com.exe4j.runtime.WinLauncher.main(WinLauncher.java:94)
Caused by: java.lang.ClassNotFoundException: javax.naming.Context
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)
... 22 more
the pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.poitest</groupId>
<artifactId>poitest</artifactId>
<version>0.1</version>
<dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>5.0.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.10</version>
</dependency>
<dependency> <!-- 桥接:告诉Slf4j使用Log4j2 -->
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.17.1</version>
</dependency>
<dependency> <!-- 桥接:告诉commons logging使用Log4j2 -->
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.1</version>
</dependency>
</dependencies>
<build>
<finalName>test</finalName>
<plugins>
<!-- define the project compile level -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>/>
<!-- 指定启动类 -->
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>poitest.test</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
the program is:
package poitest;
import java.io.File;
import java.io.FileInputStream;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.sl.extractor.SlideShowExtractor;
import org.apache.poi.xslf.extractor.XSLFExtractor;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class test {
private final static Logger m_logger = LoggerFactory.getLogger("test");
public static void main(String[] args) {
m_logger.info("begin");
test l_test = new test();
m_logger.info("create test");
String l_textString = l_test.ReadPPT("D:\\00\\chp02.pptx");
m_logger.info("D:\\00\\chp02.pptx");
System.out.println(l_textString);
System.out.println( "End" );
m_logger.info("end");
}
private String ReadPPT(final String n_FileName)
{
String l_text=new String("");
try
{
File l_fileInfo=new File(n_FileName);
if(l_fileInfo.length()<=0l)
{
//m_logger.info("ReadPPT ---{} is empty", n_FileName);
return new String("");
}
FileInputStream l_file = new FileInputStream(l_fileInfo);
if(n_FileName.endsWith(".ppt")||n_FileName.endsWith(".dps"))
{
HSLFSlideShow l_HSLFSlideShow = new HSLFSlideShow(l_file);
SlideShowExtractor l_SlideShowExtractor = new SlideShowExtractor(l_HSLFSlideShow);
l_text = l_SlideShowExtractor.getText();
}
else if(n_FileName.endsWith(".pptx"))
{
XMLSlideShow l_XMLSlideShow=new XMLSlideShow(l_file);
XSLFExtractor l_XSLFExtractor= new XSLFExtractor(l_XMLSlideShow);
l_text = l_XSLFExtractor.getText();
}
l_file.close();
}
catch (Exception e)
{
//m_logger.error("ReadPPT:{} ----Exception-{}",n_FileName, e);
}
return l_text;
}
}
Solution 1:[1]
The error says it's unable to find javax.naming.Context, and the stack trace indicates that it's happening from within the Log4J lookups code.
I'm guessing that your logging config (which you don't show) includes ${jndi:something}. The simplest solution will be to remove that lookup (and any others that start with ${jndi:).
You could also look in the documentation for Exe4J to find out why it's not including the necessary classes (which are probably something referenced by java.naming.Context).
Beware that Log4J version 2.7.1 is vulnerable to Log4Shell. You should upgrade to the latest version for the version of Java that you're using (see this).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Parsifal |
