编辑:重写问题:
我创建了一个新的最小例子来说明我的问题。这里首先是一个简单类App.java的源代码:
package testlog4j.testlog4j;
import java.io.*;
import java.net.*;
import org.apache.log4j.*;
import org.apache.log4j.xml.*;
public class App
{
static Logger logger = Logger.getLogger(App.class);
URL url = getClass().getClassLoader().getResource("log4j.xml");
public static void main( String[] args )
{
App app = new App();
DOMConfigurator.configure(app.url);
System.out.println( "Hello World!" );
System.out.println("Resource(.): " + App.class.getResource("."));
System.out.println("Resource(): " + App.class.getResource(""));
System.out.println("URL :" + app.url.toString());
logger.info("INFO");
}
}
其次,这是项目的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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>testlog4j</groupId>
<artifactId>testlog4j</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>testlog4j</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>testlog4j.testlog4j.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<configuration>
<mainClass>testlog4j.testlog4j.App</mainClass>
<attachToBuild>true</attachToBuild>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
</dependencies>
<pluginRepositories>
<pluginRepository>
<id>onejar-maven-plugin.googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginRepository>
</pluginRepositories>
</project>
第三,我在src / main / resources文件夹下有我的log4j.xml:
<?xml version="1.0" encoding="iso-8859-1"?>
<!--<!DOCTYPE log4j:configuration PUBLIC-->
<!--"-//APACHE//DTD LOG4J 1.2//EN" "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">-->
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration debug="true">
<appender name="default.console" class="org.apache.log4j.ConsoleAppender">
<param name="target" value="System.out" />
<param name="threshold" value="debug" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{1}] - %m%n" />
</layout>
</appender>
<appender name="main.file" class="org.apache.log4j.RollingFileAppender">
<param name="file" value="log/main.log" />
<param name="MaxFileSize" value="2MB" />
<param name="append" value="true" />
<param name="threshold" value="debug" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{1}] - %m%n" />
</layout>
</appender>
<logger name="testlog4j.testlog4j.App" additivity="false">
<level value="debug" />
<appender-ref ref="main.file" />
<appender-ref ref="default.console" />
</logger>
<root>
<priority value="debug" />
<appender-ref ref="default.console" />
<appender-ref ref="main.file" />
</root>
好的,构建应用程序并在Netbeans中运行完全按预期方式登录到控制台和日志目录下的文件。
但是,从命令行(普通jar和oneJar)运行不起作用,如下所示:
java -jar testlog4j-1.0.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger
at testlog4j.testlog4j.App.<clinit>(App.java:17)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Logger
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 1 more
java -jar testlog4j.1.0.one-jar.jar
log4j:ERROR Could not parse url [jar:file:/testlog4j-1.0.one-jar.jar!/main/testlog4j-1.0.jar!/log4j.xml].
java.io.FileNotFoundException: /testlog4j-1.0.one-jar.jar (No such file or directory)
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.<init>(ZipFile.java:215)
at java.util.zip.ZipFile.<init>(ZipFile.java:145)
at java.util.jar.JarFile.<init>(JarFile.java:154)
at java.util.jar.JarFile.<init>(JarFile.java:91)
at sun.net.www.protocol.jar.URLJarFile.<init>(URLJarFile.java:93)
at sun.net.www.protocol.jar.URLJarFile.getJarFile(URLJarFile.java:69)
at sun.net.www.protocol.jar.JarFileFactory.get(JarFileFactory.java:84)
at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:122)
at sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnection.java:150)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:613)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:189)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:812)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:347)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:177)
at org.apache.log4j.xml.DOMConfigurator$2.parse(DOMConfigurator.java:612)
at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:711)
at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:618)
at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:470)
at org.apache.log4j.LogManager.<clinit>(LogManager.java:122)
at org.apache.log4j.Logger.getLogger(Logger.java:117)
at testlog4j.testlog4j.App.<clinit>(App.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.simontuffs.onejar.Boot.run(Boot.java:340)
at com.simontuffs.onejar.Boot.main(Boot.java:166)
log4j:ERROR Could not parse url [jar:file:/testlog4j-1.0.one-jar.jar!/main/testlog4j-1.0.jar!/log4j.xml].
java.io.FileNotFoundException: /testlog4j-1.0.one-jar.jar (No such file or directory)
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.<init>(ZipFile.java:215)
at java.util.zip.ZipFile.<init>(ZipFile.java:145)
at java.util.jar.JarFile.<init>(JarFile.java:154)
at java.util.jar.JarFile.<init>(JarFile.java:91)
at sun.net.www.protocol.jar.URLJarFile.<init>(URLJarFile.java:93)
at sun.net.www.protocol.jar.URLJarFile.getJarFile(URLJarFile.java:69)
at sun.net.www.protocol.jar.JarFileFactory.get(JarFileFactory.java:84)
at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:122)
at sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnection.java:150)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:613)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:189)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:812)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:347)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:177)
at org.apache.log4j.xml.DOMConfigurator$2.parse(DOMConfigurator.java:612)
at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:711)
at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:618)
at org.apache.log4j.xml.DOMConfigurator.configure(DOMConfigurator.java:743)
at testlog4j.testlog4j.App.main(App.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.simontuffs.onejar.Boot.run(Boot.java:340)
at com.simontuffs.onejar.Boot.main(Boot.java:166)
Hello World!
Resource(.): null
Resource(): jar:file:/testlog4j-1.0.one-jar.jar!/main/testlog4j-1.0.jar!/testlog4j/testlog4j/
URL :jar:file:/testlog4j-1.0.one-jar.jar!/main/testlog4j-1.0.jar!/log4j.xml
log4j:WARN No appenders could be found for logger (testlog4j.testlog4j.App).
log4j:WARN Please initialize the log4j system properly.
非常感谢您的帮助。
答案 0 :(得分:5)
NoClassDefFoundError的第一个问题是设置了正确的类路径,我通过添加maven-dependencies-plugin解决了这个问题,并在maven-jar-plugin中包含了class prefix属性。
对于one-jar插件;构建one-jar文件时,log4j的DOMConfigurator.configure()方法无法再解析log4j.xml文件(如上面的问题所示)。我能够通过log4j.properties文件并使用PropertyConfigurator.configure()方法替换它。然后问题就会解决。但是,OneJar给我带来了另一个问题。因为它将第一个可执行jar构建到另一个jar中;我需要更改我的代码以找到父可执行jar的路径来写日志和属性文件。出于这个原因,我使用非弃用的单个目标更改为maven-assembly-plugin。在这种情况下,我还可以保留漂亮的log4j.xml文件。
以下是新的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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>testlog4j</groupId>
<artifactId>testlog4j</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>testlog4j</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>testlog4j.testlog4j.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>testlog4j.testlog4j.App</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
</dependencies>
<repositories>
</repositories>
</project>
此外,我将测试项目上传到github:
https://github.com/mtleis/simpleLog4jMaven
我希望有人会觉得这很有用。
答案 1 :(得分:1)
[作为答案,因为评论太久了]
对java.lang.NoClassDefFoundError:
我对NetBeans不是很熟悉,但我可以想象它在其中有效,因为NetBeans从本地Maven存储库访问target/classes
和log4
j中的类,而不是从创建的jar中访问。< / p>
您是否已解压缩jar文件并检查其中的内容?是否所有文件都在预期的正确位置? /main/testlog4j-1.0.jar!/log4j.xml
似乎不是预期的地方。