Groovy - MissingPropertyException in Class - groovy

I am completely new to Groovy and having some trouble just getting this program running. All I'm trying to do is add all the elements of one list into another, but I can't even access the variable I want in the method.
I looked around here for an answer, but all seemed to be just too specific to a person's problem or too technical for my limited understanding of Groovy. Any help is appreciated.
Using Groovy 2.4.5 in IntelliJ IDEA if that makes a difference. Here is the code I am trying to run:
class ListPractice implements Testable {
def mylist = [4,5,6]
/**
* Adds a set of elements to the mylist variable
*
* #paraelts The elements to be added
*/
def addToList(List elts) {
myList.each{
println "I: $it"
}
}
#Override
void testMe() {
addToList([7,8,9])
}
}
But it throws the following error:
Caught: groovy.lang.MissingPropertyException: No such property: myList
for class: ListPractice
Possible solutions: mylist
groovy.lang.MissingPropertyException: No such property: myList for class: ListPractice
Possible solutions: mylist
at ListPractice.addToList(ListPractice.groovy:14)
at ListPractice$addToList.callCurrent(Unknown Source)
at ListPractice.testMe(ListPractice.groovy:36)
at Testable$testMe.call(Unknown Source)
at RunMe$_main_closure1.doCall(RunMe.groovy:12)
at RunMe.main(RunMe.groovy:11)
Since this is my first time using the language and the structure of the code was done by my teacher, I'm not even sure if #Override is necessary or what it does.

Capitalisation is important
You declared your list as mylist
Then you try to call each on myList
It shows you in the error message

Related

Information-hiding in Groovy (using closures? naming conventions?)

This follows from my unsuccessful attempt to find an answer to this question from 2014.
It's not clear to me whether there might in fact be some techniques in Groovy to use closures, specifically, to hide information. All I can say is that if information on such techniques is out there it is a perfect illustration, precisely, of "information-hiding": I cannot find it!
But failing that I think my understanding now is that absolutely zero attempt to hide information (or pretend to, as in Java - bearing in mind reflection techniques) is ever made. This appears to be by design, but also due to the requirements of Groovy's dynamic nature. It seems, for example, that #CompileStatic, mentioned in the referenced question, is more about type-checking than anything else.
But in Python, for example, there is a convention (I assume still used) to make "fields which are meant to be considered private" begin with a double underscore. I've never heard anyone talking about this in connection with Groovy.
Aren't information-hiding and encapsulation, or at least conventions to encourage disciplined use of the "intimate state" of objects, good things? Any Groovy experts care to comment?
later
daggett has given an answer which is interesting in some ways, but not really what I had in mind. Consider this:
class Main {
static main( args ) {
def sm = new SecurityManager()
System.setSecurityManager( sm )
println new Bob().doSomethingProtected()
}
}
class Bob {
public doSomethingPublic() {
"public"
}
private doSomethingPrivate() {
"private"
}
protected doSomethingProtected() {
"protected"
}
}
... whichever one of these Bob methods is called it will pass with the SecurityManager not set, but fail with it set. It also doesn't matter which package it's in. Nor does it matter whether Bob is in a subpackage (for example), with #PackageScope: it is only if Main.main is given #CompileStatic that this will help (see referenced question).
I'm also not clear about precisely what you can do with a SecurityManager set in this way: is it possible to enforce private or protected (or package-private) in some way? At the moment I just don't know and will have to investigate.
As for the other suggestion, it's intriguing, but doesn't in fact deny "visibility" as suggested. You'd also need to include the following method in class A:
def getI() {
throw new Exception()
}
After that, yes, visibility is denied to every other class, whether in the same package or not, and also these "private" elements are not even visible to other objects of the same class (! - unlike Java). In that sense it does indeed deliver a very Draconian privacy. But to me it's also a bit of a hack. I'm not quite clear about this GroovyObjectSupport class or what it does, and will have to investigate it. Finally, there is little point in actually giving these fields the private modifier. As I said, the ONLY function of private in Groovy is to deny visibility of these fields to subclasses of daggett's class A here.
Having only a stark choice between a super-Draconian and hackish "private", or "unrestrictedly public", clearly represents a considerable "impoverishment" of choice of visibility compared to Java, where you have not only protected but also package-private (subject, yes yes yes, of course, to use of reflection...), and where private fields are visible to other objects of the same class.
SecurityManager
don't run following code from GroovyConsole. only from groovy command line.
def sm = new SecurityManager()
System.setSecurityManager(sm)
//without previous lines the following code will run successfully
println new ByteArrayOutputStream().buf
this will throw the following exception
Caught: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:109)
at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:131)
Caused by: java.lang.ExceptionInInitializerError
at groovy.ui.GroovyMain.run(GroovyMain.java:397)
at groovy.ui.GroovyMain.process(GroovyMain.java:370)
at groovy.ui.GroovyMain.processArgs(GroovyMain.java:129)
at groovy.ui.GroovyMain.main(GroovyMain.java:109)
... 6 more
Caused by: java.security.AccessControlException: access denied ("java.util.logging.LoggingPermission" "control")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
at java.security.AccessController.checkPermission(AccessController.java:884)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.util.logging.LogManager.checkPermission(LogManager.java:1586)
at java.util.logging.Logger.checkPermission(Logger.java:422)
at java.util.logging.Logger.setUseParentHandlers(Logger.java:1799)
at org.codehaus.groovy.runtime.StackTraceUtils.<clinit>(StackTraceUtils.java:57)
... 10 more
control access with getProperty & setProperty
class A extends GroovyObjectSupport{
private int i=555
private int j=666
def f(){
println "i=$i j=$j"
}
Object getProperty(String name){
if(name in ['i'])throw new Exception("Access to property `$name` is denied")
return super.getProperty(name)
}
}
def a=new A()
a.f()
println "a.j = ${a.j}"
println "a.i = ${a.i}"
this will allow access to member j but not to the member i outside of class.
output:
i=555 j=666
a.j = 666
Exception thrown
java.lang.Exception: Access to property `i` is denied
...
I've created a compiler extension that allows you to either selectively or globally apply compile-time checks for violation of encapsulation.  Additionally, you can enforce strong type checking and immutability checks at compile time. https://github.com/stansonhealth/ast-framework
An example:
package com.stansonhealth.ast.encapsulate
import com.stansonhealth.ast.encapsulate.Encapsulate
#Encapsulate
class TestEncapsulationFixture {
private int i
}
class TestEncapsulation {
void foo(TestEncapsulationFixture fixture) {
fixture.i++
fixture[i]++
fixture.i = 0
def x = fixture.i
}
}
Compiler output:
startup failed:
TestEncapsulation: 14: Field or property "i" not accessible for class = com.stansonhealth.ast.encapsulate.TestEncapsulationFixture
# line 14, column 21.
fixture.i++
^
TestEncapsulation: 15: Field or property "i" not accessible for class = com.stansonhealth.ast.encapsulate.TestEncapsulationFixture
# line 15, column 21.
fixture[i]++
^
TestEncapsulation: 16: Field or property "i" not accessible for class = com.stansonhealth.ast.encapsulate.TestEncapsulationFixture
# line 16, column 21.
fixture.i = 0
^
TestEncapsulation: 17: Field or property "i" not accessible for class = com.stansonhealth.ast.encapsulate.TestEncapsulationFixture
# line 17, column 29.
def x = fixture.i
^
4 errors

Groovy resolves ambiguous methods alphabetically by parameter class name

Groovy will resolve ambiguous method calls by choosing the method with a parameter type that is alphabetically first. In the following example the method that takes a parameter of type "A" will be called if Groovy calls MyClass.printIt(null).
If you refactor this code to rename class A to class C you will find that the call with a null myVariable will then resolve to the method that takes a parameter of type "B", the bottom one.
class MyTest {
public static void main(String[] args) {
B myVariable = new B()
new MyClass().printIt(myVariable)
myVariable = null
new MyClass().printIt(myVariable)
}
}
class A {}
class B {}
class MyClass {
void printIt(A variable) {
println "TOP method called"
}
void printIt(B variable) {
println "BOTTOM method called"
}
}
the code as listed above produces the following output
BOTTOM method called
TOP method called it called the top method with a variable of type B
once class A is renamed to class C the output will change to
BOTTOM method called
BOTTOM method called
try as many permutations as you like, the method that takes the class with the lowest alphabetical name is called when the variable passed in is null, even if the variable is typed for the other class.
groovy --version
Groovy Version: 2.0.5 JVM: 1.6.0_33 Vendor: Sun Microsystems Inc. OS: Windows 7
My question is why does Groovy do this, is this by design or is it a bug, is this behavior documented anywhere?
Dave
Can't reproduce this on groovy 2.1.6. Can't reproduce this on groovy 2.0.5 either.
In both use cases output is:
BOTTOM method called
TOP method called
When A is renamed to C output is
BOTTOM method called
TOP method called
Gentoo Linux, JDK 1.7.0_25,
On my groovy (3.0.7), it's even "better":
$ groovy test.groovy
BOTTOM method called
Caught: groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method MyClass#printIt.
Cannot resolve which method to invoke for [null] due to overlapping prototypes between:
[class A]
[class B]
groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method MyClass#printIt.
Cannot resolve which method to invoke for [null] due to overlapping prototypes between:
[class A]
[class B]
at MyTest.main(test.groovy:6)

Groovy closure not work with static final field from super class

class Parent {
final static String newLine = "*"
}
class Child extends Parent{
List body = [3, 4, 5]
String toString() {
def str = new StringBuilder()
body.each { str.append(it + newLine) }
str
}
}
def c = new Child()
println c
The above is one trivial sample to illustrate the problem. It couldn't be compiled using Groovy plugin on Eclipse. Remove either final or static in the field of super class solves the problem. However, I have no idea why it's the case.
http://groovy.codehaus.org/Groovy+Beans
In this link it mentions the rules for property and fields used in Groovy. I suppose the one applied should be the last one, i.e. meta class. Unfortunately, I still couldn't understand the behavior.
The behavior is reproduced consistently in all versions of Groovy. Maybe someone could report one bug to Groovy team. I have never done this before. It would be more efficient if someone experienced could do that.
This is most probably https://issues.apache.org/jira/browse/GROOVY-5776 which is more difficult to fix than it looks like
As blackdrag already pointed out: it's a bug.
But another workaround is to add the protected keyword:
protected final static String newLine = "*"

This code looks like, groovy will result in bad performance? Is it so?

I have been reading Groovy for a month or so. Recently i have came across the following code:
class MyBean implements Serializable {
def untyped
String typed
def item1, item2
def assigned = 'default value'
}
And when I do this :
def bean = new MyBean()
assert 'default value' == bean.getAssigned()
However the above code makes GroovyBeans very very impressive, but still my question is this:
Even though we haven't created the getter function(getAssigned()), groovy does for us. So is that groovy produce this for all class's even though we are not intended to work in GRoovyBeans? This means that for all class's it creates the setter and getter, even though we wont want? Is this is not the performance issue? Or else my view is worng?
Adding a method to a class won't cause a performance issue, as it doesn't have to be called.
If you want direct access to the property, you can use the Java field operator:
bean.#assigned

Can I redefine String#length?

I'd like to re-implement a method of a Java class. For example, for "hi".length() to return 4. (How) Can I do that?
I know using SomeClass.metaClass I can get a reference to an existing method and define new (or overriding) method, but I can't seem to be able to do that for existing Java methods.
Using Groovy, you can replace any method (even those of final classes) with your own implementation. Method replacement in Groovy uses the meta-object protocol, not inheritance.
Here's the example you requested, i.e. how to make String.length() always return 4
// Redefine the method
String.metaClass.invokeMethod = { name, args ->
def metaMethod = delegate.metaClass.getMetaMethod(name, args)
def result = metaMethod.invoke(delegate, args)
name == 'length' ? 4 : result
}
// Test it
assert "i_do_not_have_4_chars".length() == 4
Seems like it could be possible by abusing String metaClass. But the attempt I've done so far in groovy console didn't led to the expected result :
def oldLength = String.metaClass.length
String.metaClass.length = { ->
return oldLength+10;
}
println "hi".length()
outputs the sad 2
I think you could take a look at Proxy MetaClass or Delegating metaClass.
If you did redefine it, it would only work in Groovy code. Groovy can't change the way Java code executes.
In Groovy, "hi".length() is roughly equivalent to this Java:
stringMetaClass.invokeMethod("hi","length");
Because Groovy doesn't actually call length directly, metaClass tricks work in Groovy code. But Java doesn't know about MetaClasses, so there is no way to make this work.
Although this question is very old I like to point out another way (at least for newer Groovy versions) .
The length() method in java.lang.String is implemented from java.lang.CharSequence interface. In order to reimplement the method using the String-metaClass you need to "override" the method in the metaClass of the interface first.
CharSequence.metaClass.length = { -> -1}
String.metaClass.length = { -> 4 }
assert "i_do_not_have_4_chars".length() == 4
The solution using String.metaClass.invokeMethod changes the behaviour of all String-methods and is problematic. For instance, simply invoking "asdf".size() leads to an exception on my setup.

Resources