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

时间:2014-07-15 11:31:55

标签: java groovy version

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

经过一番翻找之后,我构建了这段代码来阅读班级的主要字节 - 请参阅/ http://en.wikipedia.org/wiki/Java_class_file#General_layout

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

class CompilerVersionSupport {

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

    assert( ins.readUnsignedShort() == 0xcafe )    
    assert( ins.readUnsignedShort() == 0xbabe )
    int minor = ins.readUnsignedShort();
    int major = ins.readUnsignedShort();
    ins.close();
    int javaVersion = major - 44 
    return "1.$javaVersion"
    }     
}

麻烦的是,它返回1.5。

可能会发生什么?

  • 查尔斯

3 个答案:

答案 0 :(得分:5)

默认的Groovy行为不是使用与正在使用的JDK相同的字节码版本来编译代码。 1.5是默认的兼容性原因,恕我直言。如果希望编译器输出较新的字节码,则需要明确设置它。

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

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

答案 1 :(得分:0)

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

在该文件中,我看到了这一点,请注意<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>

我将IntelliJ用于IDE。 IntelliJ会自动将语言级别设置为Java 1.5。即使更改它,当我重新导入项目时,它也会重置回Java 1.5(我已经模糊了敏感信息),

enter image description here

答案 2 :(得分:-1)

我认为问题在于您使用的程序来查找类版本。如果断言未启用,则流不会读取前两个无符号短路,因此后续的次要和主要读取语句分别导致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;
}
相关问题