0

问题:我的 Uber Jar / Fat jar 太大。包含的依赖项使我的 jar 大小超过 20 MB。因此,将文件上传到我正在开发的测试 VPS 通常需要几秒钟的时间。我的目标是减小 jar 文件的大小,以便我可以快速上传和测试我的代码。我的代码本身只有 500 kb 左右。由于我需要 jar 大小为 20 MB 的依赖关系。

尝试的解决方案:我知道在 gradle 中,compileOnly 范围是“在编译时需要其 API 但其实现由消费库、应用程序或运行时环境提供的依赖项”。所以我想尝试用一个空的主类创建一个空的 uber jar,但它具有我项目使用的所有依赖项。然后,我的想法是我将在运行时使用这个 uber jar 从我的实际代码 jar 中访问我的项目所需的依赖项。

问题:现在的问题是,我不知道如何在运行时将这个 uber jar 中的“实现”提供给包含我的代码的“thin jar”。我该如何解决这个问题?我知道这是可能的,因为根据我在 Minecraft 插件开发方面的背景,我知道其他插件 jar 中的方法的“实现”确实是在运行时提供的。这允许插件 jar 的大小更小。

4

1 回答 1

0

我已经找到了解决这个问题的方法。事实证明,我确实走在了正确的轨道上。如果像我一样,您的编程工作受到巨大 jar 大小的限制,请继续阅读。

再次澄清一下,这里的方法是首先创建一个没有包含所有库和依赖项的代码的空 uber jar。然后,您将该 uber jar 用作“瘦” jar 中的失重运行时库。

以下是有关如何执行此操作的分步说明:

  1. 在 gradle 上使用 shadowJar 创建一个 uber jar。使用 gradle 的“java-library”插件使用“api”范围。这将确保当您将此 uber jar 用作依赖项时,您将能够访问 uber jar 正在实现的所有库。这是一个示例 build.gradle:
plugins {
    id "java"
    id "java-library"
    id "com.github.johnrengelman.shadow"
}

group 'my.company'
version '1.0.0'

repositories {
    maven {
        url 'https://jitpack.io'
    }
    maven {
        url 'https://jcenter.bintray.com'
    }
}

dependencies {
    api 'com.fasterxml.jackson.core:jackson-core:2.10.0'
    api 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.9.8'
    api 'com.fasterxml.jackson.core:jackson-databind:2.10.0'
    api 'org.apache.httpcomponents:httpclient:4.5.6'
    api 'org.apache.httpcomponents:httpmime:4.5.6'
    api 'com.zaxxer:HikariCP:2.6.0'
    api 'mysql:mysql-connector-java:5.1.36'
}

shadowJar {
    archiveFileName = "Uber.jar"
    destinationDirectory = file("build")
}

// Force character encoding in case the workspace was not set up correctly
tasks.withType(Javadoc) {
    options.encoding = 'UTF-8'
}
  1. 现在将这个 uber jar 上传到 maven,或者任何你想要的地方,以便将 uber jar 作为依赖项添加到你的主项目中。确保将此 uber jar 添加为“compileOnly”依赖项。这是我的主项目上修改后的 build.gradle。

插件 { id "java" id "com.github.johnrengelman.shadow" }

组“my.company”版本“2.0”

存储库 { maven { url 'https://jitpack.io' } maven { url 'https://jcenter.bintray.com' } }

依赖项 { compileOnly 'my.company:uberjar:1.0.0' }

shadowJar { archiveFileName = project.name + ".jar" destinationDirectory = file("build") }

jar { manifest { attributes 'Main-Class': 'Main' // 你的主类属性 'Class-Path': 'Uber.jar' // 超级 jar 的路径 - 在这种情况下,它与 main 位于同一目录中罐。} }

// 强制字符编码以防工作区设置不正确 tasks.withType(Javadoc) { options.encoding = 'UTF-8' }

  1. 如上面我的 build.gradle 所示,真正的魔法发生在“Class-Path”选项中配置 uber jar 的路径。

  2. 编译。

  3. 现在您可以将您的 uber jar 及其库留在原处,并享受调试短而甜美的“瘦”jar 的乐趣,这只是您自己的代码:D!

于 2021-08-15T01:51:27.660 回答