程序包装到EXE中包括log4j2,运行EXE软件时会发生错误
由于POI依赖于log4j 2.7.1,因此已将log4j核和log4j-api添加到Maven中。将程序打包为JAR时没有错误。当使用EXE4J将JAR包装到EXE中时,会发生错误。 。首先,我认为log4j.xml配置文件并没有引起它,但是当我将log4j.xml放在资源文件夹中时,它仍然没有起作用。使用的开发环境是Win10 + Ecplise 2022-03 + JDK17。这是错误代码:
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
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>
程序是:
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;
}
}
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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
该错误表明它无法找到
javax.naming.context
,并且堆栈跟踪表示它是在log4j我猜想您的记录配置(您不显示)包括
$ {jndi:sometsing}
。最简单的解决方案将是删除该查找(以及以$ {JNDI:
开始开头的任何其他查找)。您还可以在文档中查看EXE4J,以了解为什么不包括必要的类(这可能是
java.naming.context
)。注意log4j版本2.7.1很容易受到log4shell的影响。您应该升级到您正在使用的Java版本的最新版本(请参阅这个)。
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).