如何使用gradle创建的fatJar中存在的main方法执行类

时间:2017-08-02 21:39:31

标签: java maven gradle

这是how to execute a built fat JAR as a gradle task?的后续问题 我没有足够的积分来提问我的问题作为评论。所以我不得不再问一次。这个问题已经多次以其他格式和场景提出,但这些回答都没有帮助我。

我的问题:

方案1:使用gradle fatJar

创建一个具有依赖关系的jar

方案2:使用maven程序集创建一个具有依赖关系的jar

执行

java -cp sample.jar com.example.ClassA

在两个进程中生成的jar文件上。

问题: 来自Process 1的jar给了我

错误:找不到或加载主类com.example.ClassA

进程2中的

jar正确执行。

我已经提取了两个jar文件,它们都具有相同的文件夹结构和相同的文件 - 这意味着编译的类文件存在于两个jar文件中。

我没有在任何一个进程中指定任何清单条目,因为我有多个主类,我不是要生成可执行的jar文件。

我的build.gradle文件如下所示:

apply plugin: 'java'
apply plugin: 'maven'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenLocal()
}

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

processResources {
    from 'src/main/resources'
}

task compile (type: JavaCompile) {
    source = sourceSets.main.java.srcDirs
    include '**/*.java'
    classpath = sourceSets.main.compileClasspath
    destinationDir = sourceSets.main.output.classesDir
}

compile.options.compilerArgs = ["-sourcepath", "$projectDir/src/main/java"]

dependencies {
    .
    .
    .

}

task fatJar(type:Jar) {
    baseName = 'xxxxxxx'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}

defaultTasks 'clean', 'compile', 'fatJar'

编辑 - 1:

我尝试了jar的相对路径,jar的绝对路径,甚至浏览到包含jar的文件夹。没有任何运气。

我尝试过使用' /'而不是'而不是'在包名称中。那里也没有运气。

我尝试使用java VM参数提供足够大的堆空间。纳达。

尝试在powershell上执行。得到以下错误:

+ CategoryInfo          : NotSpecified: (Error: Could not lo...ClassA:String) [], RemoteException

+ FullyQualifiedErrorId : NativeCommandError

我想直接看到内容,所以使用jar -tvf path_to_jar \ sample.jar。有趣的是,jar命令没有执行并抱怨在类路径上找不到命令。我不得不浏览java安装目录并执行命令,它显示了文件内容。

我这里的想法和选择已经不多了。 有什么指针吗?

2 个答案:

答案 0 :(得分:0)

看起来您的执行命令无效。用以下代码构建项目之后:

./gradlew clean fatJar

你应该使用以下命令来执行你的程序:

java -cp build/libs/xxxxxxx.jar com.example.ClassA

参数-cp build/libs/xxxxxxx.jar设置即将启动的JVM的类路径,它必须指向现有的JAR文件(您可以使用此文件的相对路径或绝对路径)。

看看我几分钟前录制的以下截屏视频:

如果我将执行命令更改为:

,您可以看到
java -cp xxxxxxx.jar com.example.ClassA

我和你的错误完全相同:

Error: Could not find or load main class com.example.ClassA

在这里,您可以找到simple Gradle project我过去常用的build.gradle文件示例。我添加了一个依赖项来证明fatJar构建了一个带有依赖项的JAR,并且我已经添加到public static void main(String[] args)的类中,以证明您可以从命令行中选择任何主类。我希望它有所帮助。

答案 1 :(得分:0)

出于某种原因,无论我为fatJar使用哪个配置,最终jar在尝试执行主类时都会出错。

使用ShadowJar任务我能够构建必要的jar并执行问题中指定的主类。

我知道这会破坏有关使用fatJar和执行主类的问题的全部目的。但由于时间限制,我不得不寻找替代方案。

对于那些正在寻找Shadow Jar任务配置的人,我是使用以下方法完成的:

buildscript {
    repositories {  
        mavenLocal()    
        dependencies {
            classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
        }
    }
}


apply plugin: 'com.github.johnrengelman.shadow'

最后执行任务,我用了

gradle shadowJar