Rao
Rao

Reputation: 21369

Groovy unable to access private property of super class using `@`

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

Answers (3)

albciff
albciff

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

Saurabh Gaur
Saurabh Gaur

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

William Greenly
William Greenly

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

Related Questions