Does anyone know if there's any way to intercept field accesses on the accessed class with Javassits?
public class Original{
public int field;
}
public class User {
Original o;
...
public int query(){
return o.field;
}
public void set(){
o.field=3;
}
}
What I want is that whenever another class accesses the field from any original instance, it runs some extra code (e.g. System.out.println("Reading field");)
I know that extending the class javassist.expr.ExprEditor and implementing the method void edit(FieldAccess fa), I can replace the field access for any other code that I want, but on the accessing class.
This requires to modify any class accessing that field. In our example the User class a replace all the read accesses by System.out.println(...);XXX=o.field, and all the write accesses by System.out.println(...);o.field=XXX
What I want to do is to convert a regular class instance into a proxy so any field access triggers a method execution. Is it feasible? Does it have any impact on possible subclasses?
Thanks in advance!
One way to do it is making all your proxy's fields private, and of course provide corresponding setters/getters, after that, you would implement a MethodHandler which will contain the method that you want to execute (ie. invoke) and you need to imeplement a MethodFilter in which you will designate which methods you want to intercept (in your case the getters/setters)
I think you're already familiar with javassist, so no code samples are needed i think, otherwise, i can edit this post to provide examples
I hope you get the idea ;)
Related
Say I have the following class:
public class FormContainer {
#EJB
private ExternalDao externalDao; // uses dependency Injection
private final OrderForm orderForm;
private final List<OrderFormContent> formContents;
public FormContainer(OrderForm orderForm) {
this.orderForm = orderForm
initializeOrderForm();
}
private void initializeOrderForm() {
formContents = externalDao.getFormContents(orderForm);
// similar for any other properties
}
// getters & setters
}
I am using this class to be able to hold all the fields that I will need to refer through the application. I am still learning good design and bad design practices so I am wondering if this bad design to initialize the properties of orderForm.
If so, how could it be improved?
It's OK.
The important rule to remember is not to allow this to "escape", which means don't let the instance be passed, directly or implicitly due to anonymous/inner classes, to another "process" (defined in the broadest terms).
The reason is that your instance may not be completely initialized when the other process gets it, which can lead to inconsistencies and weird bugs.
It's ok to call private methods from your constructor to initialize some data that used inside the class. Just be sure that your methods have no "side-effects" like long-time methods that user of your class would probably not expect with just calling your constructor.
If you have such methods, maybe you should extract Inititialize method that user of your class will use when he will be ready for it.
Given, for example, a class like this:
public abstract class AbstractSomething {
public static volatile SingularAttribute<Somefield, AnotherField> myAttribute;
}
how can I get an instance of myAttribute via reflection. There are no implementing classes for AbstractSomething.
EDIT
No, we need an instance of the SingularAttribute<T, S>. And the reason we need to use reflection is becuase these classes are generated and passed into our method as a Class object. We have no way no know which AbstractSomething we are receiving. There are quite a few of them.
EDIT 2
Found out what the issue was. When a Hibernate context is present in the application, the interfaces on the abstract class are replaced with their implementation counterparts when accessing them.
No big deal actually, you can do something like this:
Field field = AbstractSomething.class.getField("myAttribute")
And then you can access it by invoking field.get(null) and field.set(null, value)
The real question is WHY do you want to use reflection, but I guess you have your reasons.
EDIT:
If you have a Class instance in before hand (lets call it classInstance) then you can do
Field field = classInstance.getField("myAttribute")
to get the Field that reificates the field you are looking for... and if you want all fields just invoke the getFields method.
You don't really need a concrete implementation nor an instance of the reificated class in question in order to access the static fields.
No need for reflection. The field belongs to the class, and no matter how many subclasses there are, there is only one instance of the AbstractSomething class, so just:
SingularAttribute<Somefield, AnotherField> attr = AbstractSomething.myAttribute;
I have recently joined a new company and I am trying to get used to their coding style guidelines. I have no problem changing my coding style, but one particular point, I am not sure whether they are right or not.
For my first task I had to extend one of the existing abstract classes to develop a particular functionality. Thus I needed to access many attributes declared in this abstract superclass. To do so I proposed to change the visibility of these attributes and declare them as protected. My surprise came with their reply:
"Never! That is absolutely against OOP and you would produce obscure and difficult to maintain code! What you have to do is creating a getter in the super class and using it from the subclass in order to access these attributes".
Well, I have been always using protected attributes in an abstract superclass and accessing them from the subclass directly and I always thought there was nothing wrong with it. Even I would say that calling all the time the getter to access an attributes in the super class is slower than using it by its name...
What do you think about it? Is it normal/standard coding style declaring the attributes in a superclass and accessing them directly or are you of the oppinion that is better creating getters for these attributes.
To sumarize, my way:
public abstract class A {
protected String variableA="a";
public abstract methodToImplement();
}
public MyClass B extends A {
public methodToImplement() {
System.out.println(variableA.length());
}
}
Their way:
abstract class A {
protected String variableA="a";
public String getVariableA() {
return variableA;
}
public abstract methodToImplement();
}
MyClass B extends A {
public methodToImplement() {
System.out.println(getVariableA().length());
}
}
Thanks.
So as other threads already point out it appears to be so that it's indeed recommended to use getters and setters. The reason being that if you ever plan to change the representation of that value (StringBuilder instead of String for example) you will have to change your code. A getter/setter allow you to program in a way that you send the getters/setters the data you want, and they will store it in the proper field for you (e.g., appending it to the StringBuilder). So yes, it apears to have a lot of advantages, even though it's not your coding style. However, declaring the variable as protected seems pretty weird when you use a getter and a setter as well..
I personally try to avoid getters/setters when they are a bit of overkill. To me they are overkill for value variables. For reference variables they are however a good idea.
However, I think there is no right or wrong here..
I was wondering if it's possible to use a variable of a java class in another java class.Suppose variable Time is defined and calculated in Class A, how can I use it in Class B?
Other answers have suggested increasing a variable's visibility. Don't do this. It breaks encapsulation: the fact that your class uses a field to store a particular piece of information is an implementation detail; you should expose relevant information via the class's API (its methods) instead. You should make fields private in almost all cases.
Likewise, some other answers have suggested possibly making the variable static. Don't do this arbitrarily. You need to understand what static really means: it's saying that this piece of information is related to the type rather than to any one particular instance of the type. Occasionally that's appropriate, but it's generally a road towards less testable code - and in many cases it's clearly wrong. For example, a Person class may well have a name variable, but that certainly shouldn't be static - it's clearly a piece of information about a single person.
You should think carefully before exposing information anyway - consider whether there's a wider operation which the class in question could expose, instead of just giving away its data piecemeal - but when you do want to expose a field's value, use a property. For example:
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
By exposing it via a method, you can later change the implementation details without breaking existing clients.
Then from another class, you'd just call the getName() method:
// However you end up getting a reference to an instance of Person
Person person = ...;
String name = person.getName();
If you do have a static field, you can expose the value in the same way, but with a static method, which you'd call using the class name.
Be careful about returning values which are mutable, e.g. java.util.Date. This is another reason for using a getter method instead of allowing direct access to the field - you can make the method return a defensive copy where you need to.
If it is declared as public, you may use ClassA.yourVariable. On the other hand, for private access modifier, include the getter to your ClassA. On the ClassB, call ClassA.getYourVariable().
Also read about access specifiers in Java it might help.
If the variable is static, you can refer to it as A.Time from any code that has access to the variable. There's only one Time value for all of class A. If it is an instance variable, and you have an instance a of class A, you can refer to the variable as a.Time. There's a separate value for each instance of class A.
This is subject to Java's access rules:
if the field is public, any code can access it (this makes public variables kind of dangerous unless they are also declared final)
if the field is protected, only code in the same package or in a subclass of A can access it
if the field has default access, only code in the same package as class A can access it
if the field is private, only code in class A (including inner classes of A) can access it.
Alternatively, you can provide an accessor method in class A:
public class A {
. . .
public class getTime() {
return this.Time; // the "this." is optional
}
}
If you declare your Variable as public or static you will be able to access it from another class.
WHICH IS A VERY VERY BAD IDEA :)
I want to call a validation method inside a shared gwt class that i have created to store the validation logic (for user entered text fields)
suggestBox.addKeyUpHandler( new KeyUpHandler() {
public void onKeyUp(KeyUpEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
String boxText = suggestBox.getText();
if (new FieldVerifier().validUserName(boxText)) { //inner class used to instanciate the FieldVerifier class where validUserName(String ..) lives
now i could do this with a properly instanciated FieldVerifier class (rather than a inner class as above) - or indeed, perhaps make it abstract. but i have the suspicion i am missing something (ie. must be an elegant way of doing it).
looked on google code search, but didnt come across anything particularly helpful..
I'm not sure I got it, but try:
FieldVerifier.this.validUserName(boxText);
If you made the validUserName() method of FieldVerifier static then you could just call FieldVerifier.validUerName() directly, without having to instantiate a FieldVerifier object. If it's a fairly small class, though, the overhead of creating a new object is likely to be minimal.
i could do this with a properly instanciated FieldVerifier class (rather than a inner class as above)
Your use of FieldVerifier is not an inner class. It is indeed 'properly instanciated'. KeyUpHandler is an example of an anonymous inned class.
If I understand what you're trying to do, I would make validUserName() a static method. It doesn't appear to require or change any state; you just pass in something, run some verification logic on it, then return a boolean. This case is when you want to start looking at using statics.