我已经创建了一个示例应用程序来演示我面临的问题。我的示例应用程序包含带有main方法的单个类和对log4j的依赖
package com.example.foo;
public class MainClass {
private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(MainClass.class);
public static void main(String[] args) {
LOG.info("Hello Ant Build");
}
}
我在我的lib文件夹中添加了两个jar文件slf4j-api-1.7.25.jar
和slf4j-simple-1.7.25.jar
.
接下来,我创建了一个ant脚本来构建这个项目。 (这个项目在eclipse下成功运行,但这不是我需要的)
我的build.xml是
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project name="sample-app" basedir="../SampleApp" default="jar">
<property name="source.dir" value="src"/>
<property name="lib.dir" value="lib"/>
<property name="class.dir" value="bin"/>
<property name="jar.dir" value="dist"/>
<property name="jar.file" value="${jar.dir}/${ant.project.name}.jar"/>
<property name="main-class" value="com.example.foo.MainClass"/>
<path id="libraries.path">
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
</path>
<target name="clean" description="delete old files">
<delete dir="${class.dir}"/>
<delete dir="${jar.dir}"/>
</target>
<target name="compile" description="build class files" depends="clean">
<mkdir dir="${class.dir}"/>
<javac srcdir="${source.dir}" destdir="${class.dir}" includeantruntime="false">
<classpath refid="libraries.path"/>
</javac>
</target>
<target name="jar" depends="compile">
<mkdir dir="${jar.dir}"/>
<mkdir dir="${class.dir}/${lib.dir}"/>
<copy todir="${class.dir}/${lib.dir}" flatten="true">
<path refid="libraries.path"/>
</copy>
<manifestclasspath property="manifest.classpath" jarfile="${jar.file}">
<classpath refid="libraries.path"/>
</manifestclasspath>
<jar destfile="${jar.file}" basedir="${class.dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
<attribute name="Class-Path" value="${manifest.classpath}"/>
</manifest>
</jar>
</target>
</project>
这会成功创建jar文件。所有必需的类文件和jar文件都存在于jar文件中。
但是当我使用java -jar sample-app.jar
执行jar时,我得到了NoClassDefFoundError
。
$ java -jar sample-app.jar
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at com.example.foo.MainClass.<clinit>(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 1 more
Exception in thread "main"
MANIFEST.MF
文件的内容是:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.10.1
Created-By: 1.8.0_111-b14 (Oracle Corporation)
Main-Class: com.example.foo.MainClass
Class-Path: ../lib/slf4j-api-1.7.25.jar ../lib/slf4j-simple-1.7.25.jar
我无法弄清楚jar文件中有什么错误或遗漏。请帮我弄清楚我的蚂蚁脚本的问题。提前致谢。
标准类加载器不会从jar中加载jar文件(请参阅https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html)。
使用MANIFEST.MF中给定的Class-Path条目,需要将这些jar文件放在文件夹“../lib”中,这意味着执行可执行jar的目录的父文件夹中的“lib”文件夹。
其他解决方案是:
我不会推荐其中任何一个。