[英]Why does Groovy compiler apparently produce 1.5 version of Java?
在 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。
會發生什么?
Groovy 的默認行為是不使用與所使用的 JDK 相同的字節碼版本來編譯代碼。 出於兼容性原因,恕我直言,1.5 是默認值。 如果您希望編譯器輸出更新的字節碼,則需要明確設置。
例如,如果您使用 Maven 編譯代碼,則可以使用GMavenPlus插件。 請參閱targetBytecode
參數的說明。
如果您不使用 Maven,則可以使用-Dgroovy.target.bytecode=1.7
或研究特定構建工具的可能性
如果您使用 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(我已經模糊了敏感信息),
我認為問題在於您用來查找課程版本的程序。 如果斷言未啟用,則流不會讀取前兩個無符號短整型,因此隨后的次要和主要讀取語句分別導致 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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.