Java Gradle FatJar任务创建多个MANIFEST.MF文件

Java Gradle FatJar任务创建多个MANIFEST.MF文件,java,jar,Java,Jar,当我运行这个FatJar/UberJar任务时,我得到一个.jar文件,其META-INF\文件夹包含两个MANIFEST.MF文件。一个是正确的,带有我插入到任务定义中的属性,另一个只是包含“Manifest Version:1.0”这会在尝试运行应用程序时导致“找不到或加载主类”错误(我假设它只读取第一个主类,无法识别主类) MANIFEST.MF#1 清单版本:1.0 MANIFEST.MF#2: 清单版本:1.0 实施标题:同步器 主类:net.xxx.yyy.Main 重复清单的原因

当我运行这个FatJar/UberJar任务时,我得到一个.jar文件,其META-INF\文件夹包含两个MANIFEST.MF文件。一个是正确的,带有我插入到任务定义中的属性,另一个只是包含“Manifest Version:1.0”这会在尝试运行应用程序时导致“找不到或加载主类”错误(我假设它只读取第一个主类,无法识别主类)


MANIFEST.MF#1
清单版本:1.0

MANIFEST.MF#2:
清单版本:1.0
实施标题:同步器
主类:net.xxx.yyy.Main

重复清单的原因是什么?
我已尝试使用排除MANIFEST.MF

it.isDirectory() ? it : zipTree(it).matching{exclude{it.path.contains == 'META-INF'}}  
it.isDirectory() ? it : zipTree(it).matching{exclude{it.name.contains == 'MANIFEST'}}

***这些确实排除了子JAR META-INF文件夹和清单文件,因此我不确定Manifest.MF#1来自何处。这似乎是一个默认值?

在我的gradle版本中,我的代码没有得到两个清单-我只得到一个清单,其中包含清单版本:如您所述的1.0

问题似乎是您的清单闭包实际上与jar闭包没有关联。Jar任务类型分配和“with Jar”关键字不会为您执行此操作。因此,它不会被识别为jar任务的清单文件。您应该能够通过以下选项之一解决此问题:

task fatJar(type: Jar) {
    baseName = project.name

    jar.manifest {
        attributes 'Implementation-Title': 'Synchronizer',
               'Main-Class': 'net.xxx.yyy.Main'
    }     
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } with jar
}
或者,编写相同代码的更简洁的方法是在jar闭包中包含manifest和from闭包:

task fatJar(type: Jar) {
    baseName = project.name
    
    jar{
        manifest {
            attributes 'Implementation-Title': 'Synchronizer',
                   'Main-Class': 'net.xxx.yyy.Main'
        }     
        from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 
    }
}

在我的gradle版本中,我的代码没有得到2个清单-我只得到一个清单,其中包含清单版本:如您所述的1.0

问题似乎是您的清单闭包实际上与jar闭包没有关联。Jar任务类型分配和“with Jar”关键字不会为您执行此操作。因此,它不会被识别为jar任务的清单文件。您应该能够通过以下选项之一解决此问题:

task fatJar(type: Jar) {
    baseName = project.name

    jar.manifest {
        attributes 'Implementation-Title': 'Synchronizer',
               'Main-Class': 'net.xxx.yyy.Main'
    }     
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } with jar
}
或者,编写相同代码的更简洁的方法是在jar闭包中包含manifest和from闭包:

task fatJar(type: Jar) {
    baseName = project.name
    
    jar{
        manifest {
            attributes 'Implementation-Title': 'Synchronizer',
                   'Main-Class': 'net.xxx.yyy.Main'
        }     
        from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 
    }
}