Hello Groovy users/devs I am using the Groovy compiler to compile standard Java code (as in the developer wrote Java code, I am using the Groovy compiler behind the scenes). Most of it works, but I did see a few compatibility issues. Some seem like bugs, some seem like parsing differences. Will there be plans to address some of them in 5.0 or even 4.0? I am using 4.0.24
1. Interfaces with static methods are not supported 2. Calls to the outer class's super from an inner class does not work. 3. Cannot mix public and private methods with the same name and parameters 4. Groovy incorrectly compiles the accessing of InnerClass's variables when the OuterClass has a getter for it 5. Cannot call on outerclass's default method if the inner class extends that outerclass 6. Appending of strings with the appending operator on a new line (ie. `+ "test"`) would fail in groovy 7. Return with return value on a new line will be considered a return null in groovy with a non reacheable 8. Java files will use {} in annotations to define arrays which is not supported in groovy where arrays uses square brackets. Static arrays in java use {} while groovy uses []. 9, Dollar Signs in Strings need to be escaped in Groovy (Presumably because of GString capabilities) 10,. Enums in java switch/case statements must not be fully qualified, but enums in groovy case statements must be fully qualified (A fix seems to exist but it does not work as expected) 11. Groovy has trouble type inferencing for Collections. The offender is Collections.asBlah set of methods. It needs <A.Y.X> to be added explicitly 12. Single Character in Single Quotes are not considered Char 13. Division Operations return a Big Decimal rather than an Integer/Double 14. Functions that take var args will default the type of the first argument, java tries to find the common parent type from all arguments regards Saravanan
////////////////////////////////// PROBLEM 1 /////////////////////////////////// public interface InterfaceWithSingleStaticMethod { // Complains that only fields may be static public static String returnTest() { return "test"; } } ////////////////////////////////// PROBLEM 2 /////////////////////////////////// public class Wrapper { public class MyInterface { String myValue() { return "BLAHBLAH"; } public static class MyImplementation extends MyInterface { private String myValueFunction() { return super.myValue(); } private final class Builder { void init() { // This errors out with no such property super in java.lang.Class // Probably because MyImplementation automatically makes a Class reference in groovy MyImplementation.super.myValue() } } } } } ////////////////////////////////// PROBLEM 3 /////////////////////////////////// public class MethodsSameName { public String returnTest() { return "test"; } private String returnTest(List<String> list) { return "testList"; } } ////////////////////////////////// PROBLEM 4 /////////////////////////////////// public class Outer { public String description; public Outer(Inner inner) { // Groovy will compile this but the statement looks like this and will create a runtime error // String var3 = ((Outer)ScriptBytecodeAdapter.castToType(inner, Outer.class)).getDescription(); this.description = inner.description; } public String getDescription() { return description; } public static Inner inner() { return new Inner(); } public static class Inner { public String description = "test"; public Inner() { } } } ////////////////////////////////// PROBLEM 5 /////////////////////////////////// public interface Interfaces { default String myThing() { return "BLAHG" } // Groovy fails with Cannot have non-static inner class // inside a trait (com.org.interfaces.Interfaces$Inner) // Does not fare better if we add static. This will only work with abstract classes public interface Inner extends Interfaces { default String otherThing() { return myThing() } } } //////////////////////////////// PROBLEM 6 and 7 /////////////////////////////// public class Interfaces { String myThing() { // This will fail because + needs to be on the previous line // Cannot find matching method java.lang.String#positive() String a = "BLAHG" + "BLAG"; // This causes it to return null return a; } } /////////////////////////////// PROBLEM 8 ////////////////////////////////// // Groovy does not like the {} inside the annotation. Understandable, // because [] must be used but this java wont compile @SomeAnnotation(value={com.blah.INPUT_ENUM, com.blah.OUTPUT_ENUM}) class myClass { } /////////////////////////////// PROBLEM 11 ////////////////////////////////// public class Interfaces { public String myThing() { var myArray = Arrays.asList("123", "1354"); var mySet = myArray.stream().collect(Collectors.toSet()); // This call will fail // Failed to find class method 'getBytes(java.lang.Object)' or // instance method 'getBytes()' for the type: java.lang.String // To make it work change the previous line to // var mySet = myArray.stream().collect(Collectors.<String>toSet()); mySet.forEach(String::getBytes); } } /////////////////////////////// PROBLEM 14 ////////////////////////////////// public class Interfaces { class Blah { } class BlahBlah extends Blah { } class BlahBlahBlah extends Blah { } public String myThing() { // This fails with // Incompatible generic argument types. Cannot assign java.util.List<? extends com.org.interfaces.Interfaces.Blah> // to: java.util.List<com.org.interfaces.Interfaces.Blah> // To fix change to explicitly define generic type // Arrays.<Blah> asList(...) List<Blah> myArray = Arrays.asList(new Blah(), new BlahBlah(), new BlahBlahBlah(), new Blah()); } } public class Interfaces { class Blah { } class BlahBlah extends Blah { } class BlahBlahBlah extends Blah { } public String myThing() { // This fails with // Incompatible generic argument types. Cannot assign java.util.List<? extends com.org.interfaces.Interfaces.Blah> // to: java.util.List<com.org.interfaces.Interfaces.Blah> // To fix change to explicitly define generic type // Arrays.<Blah> asList(...) List<Blah> myArray = Arrays.asList(new Blah(), new BlahBlah(), new BlahBlahBlah(), new Blah()); } }