在使用Eclipse和Gradle时选择正确的JRE版本

5
我正在使用带有Eclipse插件的Gradle来生成我的项目文件,但我无法让它将正确的JRE版本放入.classpath中。我可以添加一个JRE容器,但我无法弄清如何删除默认容器 - 因为该项目在开发者之间共享,他们可能在Eclipse中设置了不同的默认值,所以我想手动控制这个过程。
我认为这应该是这样工作的:
apply plugin: 'java'
apply plugin: 'eclipse'

sourceCompatibility = 1.6

由于targetCompatibilitysourceCompatibility相同,我期望这个设置会去Eclipse设置中找到与源版本匹配的JRE(是的,在我的机器上有一个JRE安装和一个单独的JDK安装),然后使用它。

然而,它选择了默认值,而在我的机器上默认值是Java 7。

我尝试向Eclipse配置中添加一些内容:

eclipse {
    jdt {
        sourceCompatibility = 1.6 // tried with and without this
    }
    classpath {
        // tried various ways to remove the old entry, among them:
        file.beforeMerged { p -> p.entries.clear() }

        // and then I add the "correct" one
        containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.6.0_45'
    }
}

这样做,我最终在 .classpath 中会得到两个 JRE 容器:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="output" path="bin"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER" exported="true"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.6.0_45" exported="true"/>
</classpath>

如何告诉gradle我只想要JRE 1.6容器,而不是默认的容器?
一些限制条件:
- Eclipse中的默认设置应该是无关紧要的。 - 最好让脚本查找容器 - 在上面的脚本中,定义要添加的容器字符串取决于用户。我更喜欢在“已安装的JRE”中查找与sourceConfiguration版本匹配的版本 - 如果Eclipse中没有这样的JRE,则可以抛出错误。

1
此外,如果能找到一种正确配置引导类路径的方法以避免“警告:[选项]未设置引导类路径与源1.6一起使用”,并且这种方法是用户无关的(即以某种智能方式查找JRE路径),则可以获得额外的奖励分数。 - Tomas Aschan
2个回答

4
我最终以比我想象中更为手动的方式解决了这个问题,但至少它起作用了。
为了将设置与实现分离,每个开发人员都有一个未被纳入版本控制的 gradle.properties 文件。该文件包含以下信息(在我的工作站上):
javaVersion=1.6
javaPath=C:/Program/Java/jdk1.6.0_45
jdkName=jdk1.6.0_45

在构建脚本中,我接下来会执行以下步骤以确保所有配置正确:
// Set sourceCompatibility
if (project.hasProperty('javaVersion')) {
    project.sourceCompatibility = project.javaVersion
}

// Set bootClasspath - but wait until after evaluation, to have all tasks defined
project.afterEvaluate {
    if (project.hasProperty('javaPath')) {
        project.tasks.withType(AbstractCompile, {
            it.options.bootClasspath = "${project.javaPath}/jre/lib/rt.jar"
        })
    }
}

// Configure Eclipse .classpath
project.eclipse.classpath.file.whenMerged { Classpath cp ->
    if (project.hasProperty('jdkName') {
        cp.entries.findAll { it.path.contains('JRE_CONTAINER') }.each {
            it.path += "/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/$project.jdkName"
        }
    }
}

迄今为止,我已经在几个项目中使用了它,并且它工作正常,所以我猜它至少是相当可移植的,但可能需要进行轻微修改才能使其适用于其他人。


3

我发现提出的解决方案会在后续的 "gradle eclipse" 执行中导致重复条目。从Specifiy JRE Container with gradle eclipse plugin借鉴了一些代码,得到了以下代码,看起来似乎可以正常工作:

project.afterEvaluate {
  // use jre lib matching version used by project, not the workspace default
  if (project.sourceCompatibility != null) {
    def target = project.sourceCompatibility.toString()
    def containerPrefix = "org.eclipse.jdt.launching.JRE_CONTAINER"
    def containerSuffix
    if (target =~ /1.[4-5]/) {
      containerSuffix = '/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-' + target
    } else if (target =~ /1.[6-8]/) {
      containerSuffix = '/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + target
    }
    if (containerSuffix != null) {
      project.eclipse.classpath {
        containers.removeAll { it.startsWith(containerPrefix) }
        containers.add(containerPrefix + containerSuffix)
      }
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接