Java 使用gradle jar文件查找主类时出现问题

Java 使用gradle jar文件查找主类时出现问题,java,visual-studio-code,build.gradle,gradlew,Java,Visual Studio Code,Build.gradle,Gradlew,我见过很多人在使用Gradle制作jar文件时出现“找不到或加载主类”错误。我已经浏览了很多论坛,还没有找到适合我的解决方案。在一个在线教程之后,我能够在VSCode中设置一个Gradle项目,并为一个基本的hello world程序添加依赖项。链接到我在这里遵循的教程: 这对我来说没问题,但当我完成了更大的程序时,它找不到我的Main.class文件。这是我的build.gradle文件: plugins { id 'java' id 'java-library' id

我见过很多人在使用Gradle制作jar文件时出现“找不到或加载主类”错误。我已经浏览了很多论坛,还没有找到适合我的解决方案。在一个在线教程之后,我能够在VSCode中设置一个Gradle项目,并为一个基本的hello world程序添加依赖项。链接到我在这里遵循的教程: 这对我来说没问题,但当我完成了更大的程序时,它找不到我的Main.class文件。这是我的build.gradle文件:

plugins {
    id 'java'
    id 'java-library'
    id 'application'
}

application
{
    mainClass = 'Main'
}

java
{
    sourceCompatibility = JavaVersion.VERSION_12
    targetCompatibility = JavaVersion.VERSION_12
}

project.configurations.implementation.setCanBeResolved(true);
version = '1.0.0'
mainClassName = 'Main'

sourceSets
{
    main 
    {
        java
        {
            srcDirs 'src/main/java'
        }
    }
}

repositories
{
    mavenCentral()
    maven
    {
        url = 'https://licensespring-maven.s3.eu-central-1.amazonaws.com/'
    }
}

dependencies
{
    implementation 'com.licensespring:licensespring-license-client:2.1.0'
    // https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.0.0-alpha-6'
    // https://mvnrepository.com/artifact/net.harawata/appdirs
    implementation group: 'net.harawata', name: 'appdirs', version: '1.2.0'
    // https://mvnrepository.com/artifact/net.java.dev.jna/jna-platform
    implementation group: 'net.java.dev.jna', name: 'jna-platform', version: '5.6.0'
    // https://mvnrepository.com/artifact/net.java.dev.jna/jna
    implementation group: 'net.java.dev.jna', name: 'jna', version: '5.6.0'
    // https://mvnrepository.com/artifact/org.slf4j/slf4j-api
    implementation group: 'org.slf4j', name: 'slf4j-api', version: '2.0.0-alpha1'
    // https://mvnrepository.com/artifact/commons-io/commons-io
    implementation group: 'commons-io', name: 'commons-io', version: '2.7'
}

jar
{
    manifest
    {
        attributes(
            "Main-Class": "$mainClassName",
            "Class-Path": configurations.implementation.collect {it.name}.join(' ')
        )
    }
    dependsOn('dependencies')
    from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
}
src/main/java/
中,我有main.java文件和main方法以及所有其他.java文件。当我运行
gradlew clean build
时,我的
.class
文件显示在
build/classes/java/main
下。 只是澄清一下,当我运行
java-jar./build/libs/myApplication.jar'
时,我得到了
无法找到或加载主类main的错误。如果你需要更多的细节,请告诉我


更新:再次切换到Intellij,我发现涉及主清单属性的错误。我检查了输出的jar,清单文件确实已经打包,并且它确实有一个主清单属性。请帮帮我

能否尝试为main提供源集和完整包名? 它应该是这样的:

sourceSets {
    main {
        java {
            srcDirs 'src/main/java'
        }
    }
}

project.configurations.implementation.setCanBeResolved(true)

jar{
    manifest {
        attributes(
                "Main-Class": "com.xyz.Main",
                "Class-Path":  configurations.implementation.collect { it.name }.join(' ')
        )
    }
    dependsOn ('dependencies')
}

你能试着给出main的源代码集和完整的包名吗? 它应该是这样的:

sourceSets {
    main {
        java {
            srcDirs 'src/main/java'
        }
    }
}

project.configurations.implementation.setCanBeResolved(true)

jar{
    manifest {
        attributes(
                "Main-Class": "com.xyz.Main",
                "Class-Path":  configurations.implementation.collect { it.name }.join(' ')
        )
    }
    dependsOn ('dependencies')
}

我在创建runnable jar时遇到了类似的问题。我可以用下面的例子来解决它

解决方案1:创建一个包含所有依赖项的胖罐子

task fatJar(type: Jar) {
 manifest {attributes 'Main-Class': 'com.example.gradle.App'}
 from {
       configurations.compile.collect
       { it.isDirectory() ? it : zipTree(it) }
 }with jar
}
解决方案2:创建一个可运行的jar,将依赖项复制到一个目录并设置类路径

def dependsDir = "${buildDir}/libs/dependencies/"
task copyDependencies(type: Copy) {
   from configurations.compile
   into "${dependsDir}"
}

task createJar(dependsOn: copyDependencies, type: Jar) {
   manifest {
      attributes(
       'Main-Class': 'com.example.gradle.App',
       'Class-Path': configurations.compile.collect
             { 'dependencies/' + it.getName() }.join(' ')
      )}
     with jar
}

通过一个例子来了解更多信息,我在创建runnable jar时遇到了类似的问题。我可以用下面的例子来解决它

解决方案1:创建一个包含所有依赖项的胖罐子

task fatJar(type: Jar) {
 manifest {attributes 'Main-Class': 'com.example.gradle.App'}
 from {
       configurations.compile.collect
       { it.isDirectory() ? it : zipTree(it) }
 }with jar
}
解决方案2:创建一个可运行的jar,将依赖项复制到一个目录并设置类路径

def dependsDir = "${buildDir}/libs/dependencies/"
task copyDependencies(type: Copy) {
   from configurations.compile
   into "${dependsDir}"
}

task createJar(dependsOn: copyDependencies, type: Jar) {
   manifest {
      attributes(
       'Main-Class': 'com.example.gradle.App',
       'Class-Path': configurations.compile.collect
             { 'dependencies/' + it.getName() }.join(' ')
      )}
     with jar
}

通过一个例子阅读更多关于这方面的内容

我认为您是java新手,并建议您使用具有更强社区(如eclipse)的IDE。不管是哪种方法,都要检查main方法是否低于类中其他方法。或者分享澄清的代码我对java并不陌生,但我肯定不熟悉使用Gradle。我最初是用IntelliJ IDEA编写这个程序的,但试图通过IDE编译它的结果要糟糕得多。这就是为什么我用VSCode尝试了更手动的方法。main方法就在类的下面。所以代码看起来是这样的:
public class Main{public static void Main(String[]args){//Do stuff}}
。不管是哪种方法,都要检查main方法是否低于类中其他方法。或者分享澄清的代码我对java并不陌生,但我肯定不熟悉使用Gradle。我最初是用IntelliJ IDEA编写这个程序的,但试图通过IDE编译它的结果要糟糕得多。这就是为什么我用VSCode尝试了更手动的方法。main方法就在类的下面。所以代码看起来是这样的:
public class Main{public static void Main(String[]args){//Do stuff}}
共享目录结构,直到主类或git链接,如果问题仍然存在。我已经按照您建议的方式更改了build.gradle文件。不幸的是,在另一次
gradlew clean build
之后,它给了我同样的错误。我将jar文件解压缩到一个新文件夹中。在该文件夹的根目录下是我所有的
.class
文件,包括
Main.class
。这里有一个github链接:我编辑了我的评论,帮助我解决了上述问题。但是,我遇到了新的错误——java.lang.NoClassDefFoundError:com/licensespring/LicenseSpringConfiguration您正在使用Gradle 6.6,这是最近的升级。您可能想查看gradle文档docs.gradle.org/6.6.1/userguide/publishing_setup.htmlI最初在LicenseSpring API中也有同样的错误。我发现这是因为我从未告诉Gradle如何将依赖项打包到jar文件中。我从{configurations.runtimeClasspath.collect{it.isDirectory()?it:zipTree(it)}}
中阅读了所有需要添加的
。因为您的新代码删除了这一行,所以错误会再次出现。我尝试重新添加该行,删除了
NoClassDefError
,但
无法找到或加载主类main
错误返回。您是否建议切换到较旧的Gradle版本,如果是,请选择哪一个?如果问题仍然存在,请共享目录结构直到主类或git链接。我已按照您建议的方式更改了build.Gradle文件。不幸的是,在另一次
gradlew clean build
之后,它给了我同样的错误。我将jar文件解压缩到一个新文件夹中。在该文件夹的根目录下是我所有的
.class
文件,包括
Main.class
。这里有一个github链接:我编辑了我的评论,帮助我解决了上述问题。但是,我遇到了新的错误——java.lang.NoClassDefFoundError:com/licensespring/LicenseSpringConfiguration您正在使用Gradle 6.6,这是最近的升级。您可能想查看gradle文档docs.gradle.org/6.6.1/userguide/publishing_setup.htmlI最初在LicenseSpring API中也有同样的错误。我发现这是因为我从未告诉Gradle如何将依赖项打包到jar文件中。我从{configurations.runtimeClasspath.collect{it.isDirectory()?it:zipTree(it)}}
中阅读了所有需要添加的
。因为您的新代码删除了这一行,所以错误会再次出现。我尝试重新添加该行,删除了
NoClassDefError
,但
无法找到或加载主类main
错误返回。你会建议换成更老的Gradle版本吗?如果会,是哪一个?