I have created a sample application to demonstrate the problem I'm facing. My sample app contains single class with main method and a dependency on 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");
}
}
I have added two jar files slf4j-api-1.7.25.jar and slf4j-simple-1.7.25.jar in my lib folder.
Next, I have created an ant script to build this project. (This project runs successfully under eclipse, but that is not what I need)
My build.xml is
<?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>
This creates the jar file successfully. All the required class files and jar files are present in the jar file.
But when I execute the jar using java -jar sample-app.jar I get 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"
The contents of MANIFEST.MF file is:
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
I'm not able to figure out what is wrong or missing in the jar file. Please help me figure out the issue with my ant script. Thanks in advance.

Standard class loader will not load jar files from inside your jar (see https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html).
With the given Class-Path entry in MANIFEST.MF, those jar files need to be placed to folder "../lib", meaning "lib" folder in the parent folder of the directory where the executable jar is executed.
Other solutions are:
I wouldn't recommend either of these.