Reputation: 21369
There is a third party java class
in a library. Trying to extend that class in a Groovy Class
. I would like to access that private property.
The problem is that it says
No such field: firstName for class: test2.Superuser
I am sure there must be a way to access the same and manipulate the property value using groovy.
Some posts suggests to use @
before property name in order to access private property. But no luck.
Here is the sample code snippets.
User.java (a third party class of a library)
package test;
class User {
private String firstName;
private String name() {
firstName;
}
}
SuperUser.groovy (The one I am trying)
package test2
import test.User
class SuperUser extends User {
public static void main(String[] args) {
def suser = new SuperUser()
suser.@firstName = "John"
println suser.name()
}
}
Any help is appreciated.
Using below versions:
groovy : 1.8.0
jdk : 1.7.0
Upvotes: 2
Views: 6165
Reputation: 18507
Maybe I'm late, but with your Java and Groovy version you can do the follow using meta programming:
package test2
import test.User
class SuperUser extends User {
public static void main(String[] args) {
def suser = new SuperUser()
User.metaClass.setProperty(suser,'firstName','John')
println User.metaClass.getMetaMethod('name',null).invoke(suser,null)
}
}
Or as other suggest in the traditional java reflection way:
package test2
import test.User
class SuperUser extends User {
public static void main(String[] args) {
def suser = new SuperUser()
def firstNameField = SuperUser.superclass.getDeclaredField('firstName')
firstNameField.setAccessible(true)
firstNameField.set(suser,"John")
def nameMethod = SuperUser.superclass.getDeclaredMethod('name')
nameMethod.setAccessible(true)
println nameMethod.invoke(suser,null)
}
}
Upvotes: 2
Reputation: 23805
Java classes aren't able to access all of these private
fields, properties and methods. It is only the other groovy scripts that are able to access it. The example below will demonstrate the same.
You should try to create both class file name as .groovy
instead .java
User.groovy :
class User {
private String firstName;
private String name() {
firstName;
}
}
UserTest.groovy :-
class UserTest {
public static void main(String[] args) {
User user = new User();
user.@firstName = "John"
println user.name()
}
}
Output :- John
It's working fine with Java 8
and groovy-all-2.4.3
Note:- Follow this link for more details
Edited :- If you don't want to change super class because of third party code, you should try using java reflection to access private property of a class.
Upvotes: 3
Reputation: 3989
User.java is a Java class and not a Groovy class, so those variables are still private (unlike Groovy Variables which are always public to other Groovy classes).
So in the example above, unless the Java class includes some getters and setters, you will not be able to modify it's private members.
Upvotes: 1