The Artima Developer Community
Sponsored Link

Legacy Design Forum
Finalization and Cleanup

Advertisement

Advertisement

This page contains an archived post to the Design Forum (formerly called the Flexible Java Forum) made prior to February 25, 2002. If you wish to participate in discussions, please visit the new Artima Forums.

Message:

magic in garbage collector

Posted by wouter van der meiden on August 10, 2001 at 6:41 AM

> I'm studying to take the SCJP2 exam and ran into an interesting (I think) question. Only sublclasses and classes in the same package are supposed to be able to call a protected method, so how does the Java Garbage Collector call finalize when the signature is "protected finalize() throws Throwable"?
since JDK 1.2 it is possible to call private or protected methods through the reflection api.
Example code:


import java.lang.reflect.Method;

class UnProtected {
private static void run() {
System.out.println("hello, i am private");
}
}

public class NoEncaps {
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("UnProtected"); // 1
Method m = clazz.getDeclaredMethod("run", null); // 2
m.setAccessible(true); // 3
m.invoke(null, null); // 4
}
}


when running
$ java NoEncaps
class Unprotected will be loaded into the JVM (line 1) and all the information
from the bytecode in file "Unprotected.class" is accessable through an object of type Class,
referred to by reference clazz. E.g, in line 2 we ask for a method called
"run" with an empty argument list and get a reference m.
Also for private methods, such a refernce is returned.

Retrieving information about a class from within a java
program through its Clazz object is a technique called reflection.

In JDK 1.1, we can not abuse such method references to invoke
private methods: access is still checked at the moment of method
invocation and a java.lang.IllegalAccessException occurs.

In JDK 1.2, we may call m.setAccessible(true), which turns
this check off.
In JDK 1.2 this works for applications that do not have a
security manager. When running an application with
the default securitymanager, the call to m.setAccessible is
not allowed
java -Djava.security.manager NoEncaps
will result in a
java.lang.reflect.ReflectPermission

permission to call m.setAccessable can be switched on
in a security policy file

// NoEncaps.policy
grant {
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
};

run
java -Djava.security.manager -Djava.security.policy=NoEncaps.policy NoEncaps
and the call to m.setAccessible() is allowed and therefor invocation of the
method m refers to is possible again.

another example of where such magic is used is serialization.
when you want to write (a binary representation of) an
object to file, and you want to do that in a specific way,
you need to implement private methods that will be called
by some generic 'write a binary representation'-algorithm.

In JDK 1.1 you had to bypass javas protections in C, through
the Java Native Interface (JNI).
Since JDK 1.2 you can do the magic with reflection, staying
within the java language proper.







Replies:

Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2009 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us