You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Daniel Perano (JIRA)" <ji...@apache.org> on 2016/10/30 08:46:58 UTC

[jira] [Updated] (GROOVY-7982) CompileStatic causes GroovyCastException when calling static methods on a Java class

     [ https://issues.apache.org/jira/browse/GROOVY-7982?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Daniel Perano updated GROOVY-7982:
----------------------------------
    Description: 
I have a project with mixed Java and Groovy sources. A Gradle build compiles the Java sources with javac and the Groovy sources with groovyc. There is a Java class that provides access to a database via static methods. The relevant methods in this class are shown below:

{code:Java|title=Database.java}
public class Database {
    public boolean alreadyExists(String name){}
    public boolean alreadyExists(UUID id){}
    public void save(DataClass data){}
}
{code}

The Groovy code that causes the GroovyCastException to be thrown is shown below:
{code:Java|title=DBAccess.groovy}
// name is an instance of java.lang.String
// data is an instance of DataClass (see Database.java snippet above)
if(!Database.alreadyExists(name)){
    Database.save(data)
    // ...
}else{
    // ...
}
{code}

When the Groovy snippet above runs, the call to Database.alreadyExists() produces the following stack trace:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'class mypackage.Database' with class 'java.lang.Class' to class 'mypackage.Database'
	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405)
	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319)
	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232)
	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:603)
	at myotherpackage.DBAccess.doStuff(DBAccess.groovy:56)

However, if the if statement is removed, the Database.save() method completes successfully. Decompiling the DBAccess.class file produces the following:

{code:Java|title=CompiledDBAccess.java}
if (!((Database)ScriptBytecodeAdapter.castToType(Database.class, Database.class)).alreadyExists(name)) {
     Database.save((DataClass)data);
     //...
} else {
      //...
}
{code}

  was:
I have a project with mixed Java and Groovy sources. A Gradle build compiles the Java sources with javac and the Groovy sources with groovyc. There is a Java class that provides access to a database via static methods. The relevant methods in this class are shown below:

{code:Java|title=Database.java}
public class Database {
    public boolean alreadyExists(String name){}
    public boolean alreadyExists(UUID id){}
    public void save(DataClass data){}
}
{code}

The Groovy code that causes the GroovyCastException to be thrown is shown below:
{code:Groovy|title=DBAccess.groovy}
// name is an instance of java.lang.String
// data is an instance of DataClass (see Database.java snippet above)
if(!Database.alreadyExists(name)){
    Database.save(data)
    // ...
}else{
    // ...
}
{code}

When the Groovy snippet above runs, the call to Database.alreadyExists() produces the following stack trace:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'class mypackage.Database' with class 'java.lang.Class' to class 'mypackage.Database'
	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405)
	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319)
	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232)
	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:603)
	at myotherpackage.DBAccess.doStuff(DBAccess.groovy:56)

However, if the if statement is removed, the Database.save() method completes successfully. Decompiling the DBAccess.class file produces the following:

{code:Java|title=CompiledDBAccess.java}
if (!((Database)ScriptBytecodeAdapter.castToType(Database.class, Database.class)).alreadyExists(name)) {
     Database.save((DataClass)data);
     //...
} else {
      //...
}
{code}


> CompileStatic causes GroovyCastException when calling static methods on a Java class
> ------------------------------------------------------------------------------------
>
>                 Key: GROOVY-7982
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7982
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 2.4.7
>            Reporter: Daniel Perano
>              Labels: patch
>
> I have a project with mixed Java and Groovy sources. A Gradle build compiles the Java sources with javac and the Groovy sources with groovyc. There is a Java class that provides access to a database via static methods. The relevant methods in this class are shown below:
> {code:Java|title=Database.java}
> public class Database {
>     public boolean alreadyExists(String name){}
>     public boolean alreadyExists(UUID id){}
>     public void save(DataClass data){}
> }
> {code}
> The Groovy code that causes the GroovyCastException to be thrown is shown below:
> {code:Java|title=DBAccess.groovy}
> // name is an instance of java.lang.String
> // data is an instance of DataClass (see Database.java snippet above)
> if(!Database.alreadyExists(name)){
>     Database.save(data)
>     // ...
> }else{
>     // ...
> }
> {code}
> When the Groovy snippet above runs, the call to Database.alreadyExists() produces the following stack trace:
> org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'class mypackage.Database' with class 'java.lang.Class' to class 'mypackage.Database'
> 	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405)
> 	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319)
> 	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232)
> 	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:603)
> 	at myotherpackage.DBAccess.doStuff(DBAccess.groovy:56)
> However, if the if statement is removed, the Database.save() method completes successfully. Decompiling the DBAccess.class file produces the following:
> {code:Java|title=CompiledDBAccess.java}
> if (!((Database)ScriptBytecodeAdapter.castToType(Database.class, Database.class)).alreadyExists(name)) {
>      Database.save((DataClass)data);
>      //...
> } else {
>       //...
> }
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)