Groovy转换 - 从Java

4

我有以下Java类的小部分:

public class GBitMaskTest {

    @Test
    public void checkFirstBitTest() {
        BitMask bm = new BitMask(0x8000000000000000L);
        assertEquals(true, bm.isBitSet(63));
    }

...
}

这段代码应该可以在Groovy中被编译,因为它是有效的Java代码。但是我却得到了以下错误:

Groovy Bug --- exception in phase 'conversion' in source unit '/home/g-ut-example/src/test/groovy/com/soebes/training/maven/simple/GBitMaskTest.groovy' For input string: "8000000000000000"
BUG! exception in phase 'conversion' in source unit '/home/g-ut-example/src/test/groovy/com/soebes/training/maven/simple/GBitMaskTest.groovy' For input string: "8000000000000000"

也许我对某个事情有误解。有人有想法吗?

这种情况发生在Groovy 2.0与Maven的关系中。它是在这个例子中出现的:https://github.com/khmarbaise/maui/tree/master/src/main/resources/g-ut-example,它产生了这个问题。我正在使用以下部分进行编译:

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <compilerId>groovy-eclipse-compiler</compilerId>
          <compilerArgument>nowarn</compilerArgument>
          <verbose>true</verbose>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-eclipse-compiler</artifactId>
            <version>2.7.0-01</version>
          </dependency>
          <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-eclipse-batch</artifactId>
            <version>2.0.0-01</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>

错误信息的其余部分(EXception):
GBitMaskTest.groovy' For input string: "8000000000000000"
    at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:1001)
    at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:624)
    at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:600)
    at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:577)
    at org.codehaus.jdt.groovy.internal.compiler.ast.GroovyCompilationUnitDeclaration.processToPhase(GroovyCompilationUnitDeclaration.java:171)
    at org.codehaus.jdt.groovy.internal.compiler.ast.GroovyParser.dietParse(GroovyParser.java:455)
    at org.codehaus.jdt.groovy.integration.internal.MultiplexingParser.dietParse(MultiplexingParser.java:44)
    at org.eclipse.jdt.internal.compiler.Compiler.internalBeginToCompile(Compiler.java:775)
    at org.eclipse.jdt.internal.compiler.Compiler.beginToCompile(Compiler.java:395)
    at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:485)
    at org.eclipse.jdt.internal.compiler.batch.Main.performCompilation(Main.java:3829)
    at org.eclipse.jdt.internal.compiler.batch.Main.compile(Main.java:1682)
    at org.codehaus.groovy.eclipse.compiler.GroovyEclipseCompiler.compile(GroovyEclipseCompiler.java:243)
    at org.apache.maven.plugin.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:678)
    at org.apache.maven.plugin.TestCompilerMojo.execute(TestCompilerMojo.java:161)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: java.lang.NumberFormatException: For input string: "8000000000000000"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
    at java.lang.Long.parseLong(Long.java:422)
    at org.codehaus.groovy.syntax.Numbers.parseInteger(Numbers.java:215)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.integerExpression(AntlrParserPlugin.java:3184)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.expressionSwitch(AntlrParserPlugin.java:2153)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.expression(AntlrParserPlugin.java:2018)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.expression(AntlrParserPlugin.java:2008)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.expressionSwitch(AntlrParserPlugin.java:2046)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.expression(AntlrParserPlugin.java:2018)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.expression(AntlrParserPlugin.java:2008)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.addArgumentExpression(AntlrParserPlugin.java:3071)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.arguments(AntlrParserPlugin.java:2994)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.constructorCallExpression(AntlrParserPlugin.java:2932)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.expressionSwitch(AntlrParserPlugin.java:2069)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.expression(AntlrParserPlugin.java:2018)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.expression(AntlrParserPlugin.java:2008)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.declarationExpression(AntlrParserPlugin.java:1776)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.variableDef(AntlrParserPlugin.java:1792)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.statement(AntlrParserPlugin.java:1513)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.statementListNoChild(AntlrParserPlugin.java:1599)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.statementList(AntlrParserPlugin.java:1574)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.methodDef(AntlrParserPlugin.java:1045)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.objectBlock(AntlrParserPlugin.java:800)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.innerClassDef(AntlrParserPlugin.java:783)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.classDef(AntlrParserPlugin.java:677)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.convertGroovy(AntlrParserPlugin.java:361)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.buildAST(AntlrParserPlugin.java:269)
    at org.codehaus.groovy.control.SourceUnit.convert(SourceUnit.java:302)
    at org.codehaus.groovy.control.CompilationUnit$3.call(CompilationUnit.java:706)
    at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:992)
    ... 35 more

哪个版本的Groovy?我猜这是一个JUnit测试? - tim_yates
Groovy版本2。已根据我的问题和信息进行了更新。 - khmarbaise
1个回答

3
我很惊讶这段Java代码可以编译通过,因为0x8000000000000000L大于Long.MAX_VALUE。看起来Java将其视为无符号值。建议改用-0x8000000000000000L,它的位值相同,但在long类型的合法范围内,并且在Java和Groovy中均可工作。
编辑:根据Java语言规范§3.10.1,十进制字面量超过Long.MAX_VALUE是非法的,但十六进制字面量不是,只要它们适合64位。所以这似乎是有效的Java代码。

+1 不应该导致 BUG!尽管可能与添加到 Jira 有关,如果它与 Groovy 2 相关。 - tim_yates
0x8000000000000000L 这正是 Long.MIN_VALUE 的值,我认为应该可以编译,当然它比 Long.MAX_VALUE 大,因为 Long.MAX_VALUE 是最大的正值,而 0x8000000000000000L 是最大的负值。 - khmarbaise
0x8000000000000000L应该至少可以在Java中编译,因为它在语言规范中是明确允许的。它等同于Long.MIN_VALUE,但实际上被解释为小于Long.MAX_VALUE。它是一个负值,因为它溢出到符号位。 - ataylor

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