为什么Groovy编译器显然会产生1.5版本的Java?

为什么Groovy编译器显然会产生1.5版本的Java?,java,groovy,version,Java,Groovy,Version,在JSE版本之间存在一些差异问题之后,我尝试记录用于编译的Java编译器版本(实际上是Groovy 2.1.9、Grails 2.3.8、Java 1.7.060) 经过反复搜索,我构建了这段代码来读取类的前导字节-请参见/ (更改类的路径以匹配包名称): 问题是,它返回1.5 会发生什么事 查尔斯 Groovy的默认行为不是使用与所用JDK相同的字节码版本编译代码。1.5是出于兼容性原因的默认值,IMHO。如果希望编译器输出较新的字节码,则需要显式设置 例如,如果您使用Maven编译代码,您

在JSE版本之间存在一些差异问题之后,我尝试记录用于编译的Java编译器版本(实际上是Groovy 2.1.9、Grails 2.3.8、Java 1.7.060)

经过反复搜索,我构建了这段代码来读取类的前导字节-请参见/

(更改类的路径以匹配包名称):

问题是,它返回1.5

会发生什么事

  • 查尔斯

Groovy的默认行为不是使用与所用JDK相同的字节码版本编译代码。1.5是出于兼容性原因的默认值,IMHO。如果希望编译器输出较新的字节码,则需要显式设置

例如,如果您使用Maven编译代码,您可以使用插件。请参阅
targetBytecode
参数的说明


如果您不使用Maven,可以使用
-Dgroovy.target.bytecode=1.7
或研究特定构建工具的可能性

我认为问题在于您用于查找类版本的程序。如果未启用断言,则流不会读取前两个未签名的短语句,因此后续的次要和主要读取语句分别产生0Xcafe和0xbabe。尝试启用断言或尝试使用if检查

public static String getVersion() throws Exception {
    String classAsPath = "com/my/organisation/CompilerVersionSupport.class";
    InputStream stream = (new CompilerVersionSupport()).getClass().getClassLoader().getResourceAsStream(classAsPath);
    DataInputStream ins = new DataInputStream(stream);

    if(ins.readUnsignedShort() != 0xcafe) throw new AssertionError("Invalid Class");
    if(ins.readUnsignedShort() != 0xbabe) throw new AssertionError("Invalid Class");
    int minor = ins.readUnsignedShort();
    int major = ins.readUnsignedShort();
    ins.close();
    int javaVersion = major - 44;
    return "1." + javaVersion;
}

如果您使用Maven作为构建工具,那么很可能是使用
gmavenplus插件来编译Groovy。为了找到生成的字节码的目标Java版本,我插入了我的应用程序使用的
gmavenplus插件的pom:
~/.m2/repository/org/codehaus/gmavenplus/gmavenplus plugin/1.5/gmavenplus-plugin-1.5.pom

在那个文件里我看到了这个,注意


UTF-8
UTF-8
2.2.1
2.7
2.10.1
1.5
2.10
3.2
4.12
2.18.1
3.4
2.4
2.4.1
...
org.apache.maven.plugins

您是如何编译的?您指定了任何目标版本吗?在BuildConfig.groovy:grails.project.target.level=1.7中,这个问题在()之前就出现过,但没有得到真正的回答。这里完全是一派胡言,但您是否尝试将grails.project.source.level和grails.project.target.level都设置为1.7?哦,您是否也直接使用grails?或者您正在将Grails与其他构建工具(Gradle、Maven等)集成?如果是这样,您可能需要在构建工具和Grails本身中设置所需的字节码。@Keegan-谢谢您的建议。但是是的,这两项都设置好了,而且是的,直接运行grails。“1.5是出于兼容性原因的默认值”您从哪里获得这些信息的?有没有关于如何使用grails的建议?我将groovy.target.bytecode=1.7放在BuildConfig.groovy中,但我不相信它会查看它,因为它也不会反对一个愚蠢的值。这并不完全正确,这取决于您的环境。1.5是GMavenPlus的默认值(遵循Maven编译器插件建立的模式)。Gradle默认为编译时使用的任何JDK。我假设Gant将采用Groovyc设置的默认值(不同,取决于Groovy版本)。Grails似乎除了Gant的默认值之外还有自己的默认值。@xwid我用“IMHO”结束了这句话(我不是说这是绝对真理)。但对我来说,这是最合理的解释——除非绝对必要,否则不要切断人们运行旧Java版本。我认为,当他们决定不再接受1.5字节码所提供的功能时,他们会更上一层楼。为了进一步澄清这一点:Groovy和2.1.9(由@CharlesW使用)的最新版本在没有手动覆盖的情况下都将1.5作为默认值。检查Groovy。感谢您的回复,但如果这是真的,我想我会得到0xbabe作为值,而不是49。
public static String getVersion() throws Exception {
    String classAsPath = "com/my/organisation/CompilerVersionSupport.class";
    InputStream stream = (new CompilerVersionSupport()).getClass().getClassLoader().getResourceAsStream(classAsPath);
    DataInputStream ins = new DataInputStream(stream);

    if(ins.readUnsignedShort() != 0xcafe) throw new AssertionError("Invalid Class");
    if(ins.readUnsignedShort() != 0xbabe) throw new AssertionError("Invalid Class");
    int minor = ins.readUnsignedShort();
    int major = ins.readUnsignedShort();
    ins.close();
    int javaVersion = major - 44;
    return "1." + javaVersion;
}
 <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <mavenVersion>2.2.1</mavenVersion>
    <coberturaPluginVersion>2.7</coberturaPluginVersion>
    <javadocPluginVersion>2.10.1</javadocPluginVersion>
    <!-- these are properties so integration tests can use them -->
    <javaVersion>1.5</javaVersion>
    <dependencyPluginVersion>2.10</dependencyPluginVersion>
    <compilerPluginVersion>3.2</compilerPluginVersion>
    <junitVersion>4.12</junitVersion>
    <surefirePluginVersion>2.18.1</surefirePluginVersion>
    <pluginPluginVersion>3.4</pluginPluginVersion>
    <!-- this is a property so that site generation can use it -->
    <sourcePluginVersion>2.4</sourcePluginVersion>
    <!-- this is a property so that site generation and integration tests can use it -->
    <groovyVersion>2.4.1</groovyVersion>
  </properties>
...
<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${compilerPluginVersion}</version>
        <configuration>
          <source>${javaVersion}</source>
          <target>${javaVersion}</target>
        </configuration>
      </plugin>