MyClass1:
package reflect;
public class MyClass1 {
private String name;
public MyClass1(String name) { this.name = name; }
public MyClass1() { this.name =
"<none>"; }
public String getName() { return name; }
public String toString() { return getClass().getName() +
": " + getName(); }
}
MyClass2 is identical; just a name change. Here's the aspect:
package reflect;
import java.util.Set;
import java.util.HashSet;
public aspect ReflectionWatcher {
// Watch for a particular class being fetched with reflection.
pointcut forNameCall() :
call(Class<?> Class.forName(String));
after() returning(Class<?> clazz): forNameCall() {
if (clazz == MyClass1.class)
System.out.println("Reflecting "+clazz.getName());
}
// Watch for an instance being created with reflection.
pointcut newInstanceCall(): call(Object Class.newInstance());
static Set reflectedObjects = new HashSet();
after() returning(Object instance): newInstanceCall() {
reflectedObjects.add(instance);
}
pointcut objectCall(MyClass1 obj1) : call (* *.*(..))
&& target(obj1)
&& if (reflectedObjects.contains(obj1));
before(MyClass1 obj1): objectCall(obj1) {
// Be careful here about calling methods on obj1, like toString();
// infinite recursion lurks here! fix with !cflowbelow(...)
System.out.println("Calling method on reflected object!");
}
}
(I would break this up a little for a real implementation ;) The first pointcut and after advice prints a message anytime Class.forName() is
used. The second pointcut and after returning advice remembers all objects that were constructed with Class.newInstance(). WARNING:
these objects will never be garbage collected unless you either (i) remove them from the set at some point or (ii) use a weak data structure...
Finally, the last pointcut and before advise prints a message if any method is called on any of these objects reflected objects.
If you run main, you should see this:
Normal MyClass1: myclass1
Normal MyClass2: myclass2
Reflecting reflect.MyClass1
Calling method on reflected object!
Reflected MyClass1: <none>
Reflected MyClass2: <none>
dean
On Jan 13, 2008, at 10:43 AM, Dehua Zhang wrote:
This will not work since the target is the object of type java.lang.reflex.*.
Try the following, you will see,
public privileged aspect BlockReflection
{
pointcut captureReflection(): call(*
java.lang.reflect..*.*(..));
before() : captureReflection()
{
System.out.println("target type: " + thisJoinPoint.getTarget().getClass());
}
}
You may also want have a look at
http://www.eclipse.org/aspectj/doc/released/faq.php#q:reflectiveCalls.
--
Dehua Zhang
Sable Research Group, McGill University
Montréal, Québec, Canada
http://www.cs.mcgill.ca/~dzhang25
-----Original Message-----
From: aspectj-users-bounces@xxxxxxxxxxx
on behalf of Rob Austin
Sent: Sun 1/13/2008 10:17
To: aspectj-users@xxxxxxxxxxx
Subject: [aspectj-users] Preventing Reflection
Hi,
Can you tell me if it's possible to catch reflection on a specific class,
and where reflection does occur get a handle on the target object?
Something like this, except that this doesn't work:
public privileged aspect BlockReflection
{
pointcut captureReflection(apoptotic.bookTrading.BookSellerAgent seller):
call(* java.lang.reflect..*.*(..)) && target(seller);
before(apoptotic.bookTrading.BookSellerAgent
seller) :
captureReflection(seller)
{
// call a method on the object which was targetted by reflection
seller.takeDown();
}
}
Really appreciate it.
Rob
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users