为了账号安全,请及时绑定邮箱和手机立即绑定

是否可以换出JavaExecAction Gradle用于运行Java?

是否可以换出JavaExecAction Gradle用于运行Java?

狐的传说 2021-05-05 13:34:56
当类路径太长时,Java无法启动。在Windows上,长度限制特别短。Gradle似乎对解决这个问题不感兴趣(尽管这是他们的责任,因为他们是Java的开发者),所以我们最终JavaExec用自己的替代方法代替了任务。替代方法如下所示:public class WorkingJavaExec extends JavaExec {    private static final String MATCH_CHUNKS_OF_70_CHARACTERS =        "(?<=\\G.{70})";    private final Logger logger = LoggerFactory.getLogger(getClass());    @Override    public void exec() {        FileCollection oldClasspath = getClasspath();        File jarFile = null;        try {            if (!oldClasspath.isEmpty()) {                try {                    jarFile =                        toJarWithClasspath(oldClasspath.getFiles());                    setClasspath(getProject().files(jarFile));                } catch (IOException e) {                    throw new UncheckedIOException(e);                }            }            super.exec();        } finally {            setClasspath(oldClasspath);            if (jarFile != null) {                try {                    Files.delete(jarFile.toPath());                } catch (Exception e) {                    logger.warn("Couldn't delete: " + jarFile, e);                }            }        }    }    public static File toJarWithClasspath(Set<File> files)            throws IOException {        File jarFile = File.createTempFile("long-classpath", ".jar");        try (ZipOutputStream zip =                new ZipOutputStream(new FileOutputStream(jarFile))) {            zip.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));            try (PrintWriter writer =                    new PrintWriter(                        new OutputStreamWriter(                            zip, StandardCharsets.UTF_8))) {                writer.println("Manifest-Version: 1.0");但是,使用它很麻烦,因为到处都有人可能跑来跑去JavaExec,我必须将其替换为WorkingJavaExec。新开发人员首先也不知道Gradle中存在这种陷阱,因此他们甚至不知道这是他们必须解决的问题。在阅读Gradle的内部知识时,我看到JavaExec内部使用aJavaExecAction来执行实际的exec。我认为也许可以通过替换它来解决问题,就像Gradle自己解决了该问题一样,也许它也可以应用于其他任务,例如Test。但是我在任何地方都找不到任何示例。(即使在其他大型项目中,您也希望遇到同样的问题!)是否可以替代JavaExecAction,如果可以,如何替代?
查看完整描述

2 回答

?
守着一只汪

TA贡献1872条经验 获得超3个赞

您可以使用该jar任务为您的清单添加类路径:


jar {

    baseName = "my-app"

    version =  "1.0.0"

    manifest {

        attributes("Class-Path": configurations.compile.collect { it.getName() }.join(' '))

    }

}

然后,您可以在启动时引用该jar:


task run(type:JavaExec) {

    classpath = jar.outputs.files

    main = "myapp.MainClass"

}

这可以解决命令行路径限制。您可能还希望将依赖关系JAR复制到输出文件夹,以便它们在运行时可用。


task copyDependencies(type: Copy, dependsOn: [ "build" ]) {

   from configurations.runtime

   into "./build/libs"

}


build.finalizedBy(copyDependencies)

有帮助吗?


查看完整回答
反对 回复 2021-05-19
  • 2 回答
  • 0 关注
  • 149 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信