HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"Under the Hood: java.lang.reflect.Proxy"
Vol. 7, Issue 2, p. 68

	


Listing 1: Issue interface: Issue.java

package com.dotcom;


public interface Issue
{
        public void escalate( Person by, int amount );
        public void resolve( Person by, String resolution );
        public void defer( Person by, String resolution )
                throws CannotDeferException;
        public int getPriority( Person by );
}



Listing 2: Generic handler method: LoggingInvocationHandler.java

package com.dotcom;


import java.lang.reflect.*;


class LoggingInvocationHandler
        implements InvocationHandler
{
        private Class clazz;
        private Object forObject;


        public LoggingInvocationHandler( Class c, Object o )
        {
                this.clazz = c;
                this.forObject = o;
        }


        public Object invoke( Object proxy,
                              Method method,
                              Object[] args )
                throws IllegalAccessException,
                       InvocationTargetException
        {
                try
                {
                        //  execute the underlying method:
                        Object ret = method.invoke( forObject, args );


                        //  log the call & return code:
                        LogManager.log(
                                clazz.getName(),
                                method.getName(),
                                args,
                                ret );


                        return( ret );
                }
                catch( InvocationTargetException ex )
                {
                        //  log the call & exception thrown:
                        LogManager.log(
                                clazz.getName(),
                                method.getName(),
                                args,
                                ex.getTargetException() );


                        throw ex;
                }
        }
}



Listing 3: Class capture: JVM_OnLoad

extern "C" JNIEXPORT jint JNICALL JVM_OnLoad(
        JavaVM *jvm,
        char *options,
        void *reserved )
{
        //  read options into global base path variable
        parseArguments( options );


        //  get a pointer to the JVMPI interface
        if( jvm->GetEnv( (void **)&jvmpi, JVMPI_VERSION_1 ) < 0 )
        {
                trace( "Error enabling JVMPI\n" );
                return JNI_ERR;
        }


        jvmpi->NotifyEvent = notifyEvent;
        jvmpi->EnableEvent( JVMPI_EVENT_CLASS_LOAD_HOOK, NULL );
        return JNI_OK;
}



Listing 4: 

Class capture: notifyEvent()
void notifyEvent( JVMPI_Event *event )
{
        if( event->event_type != JVMPI_EVENT_CLASS_LOAD_HOOK )
                return;


        //
        // We're passed an event structure like:
        //
        //  struct {
        //        unsigned char *class_data;
        //        jint class_data_len;
        //        unsigned char *new_class_data;
        //        jint new_class_data_len;
        //        void * (*malloc_f)(unsigned int);
        //  } class_load_hook;


        unsigned char* class_data =
                event->u.class_load_hook.class_data;


        jint class_data_len =
                event->u.class_load_hook.class_data_len;


        //  Leave the class unchanged
        copyUnchangedClassBytes( event );


        //  Getting the name of a class from the class
        //  bytes isn't exactly straightforward, I'll
        //  spare you the details:
        const char* path = getClassPath( class_data );


        //  make directories if necessary
        ensurePathAvailable( path );


        //  Write out the class bytes as we were given them
        FILE* f = fopen( path, "wb" );


        delete[] const_cast<char*>( path );
        path = 0;


        if( !f ) return;


        fwrite( class_data, class_data_len, 1, f );
        fclose( f );
}



Listing 5: Decompiled proxy class: $Proxy0.java

import com.dotcom.Issue;
import com.dotcom.Person;
import java.lang.reflect.*;


public final class $Proxy0
        extends Proxy implements Issue
{
        public $Proxy0(InvocationHandler h)
        {
                super( h );
        }


        private static Method m_defer =
                Issue.class.getMethod(
                        "defer",
                        new Class[] { Person.class, String.class }
                );


        private static Method m_escalate =
                Issue.class.getMethod(
                        "escalate",
                        new Class[] { Person.class, Integer.TYPE }
                );


        private static Method m_getPriority =
                Issue.class.getMethod(
                        "getPriority",
                        new Class[] { Person.class }
                );


        private static Method m_resolve =
                Issue.class.getMethod(
                        "resolve",
                        new Class[] { Person.class, String.class }
                );


        private static Method m_hashCode =
                Object.class.getMethod(
                        "hashCode",
                        new Class[0]
                );


        private static Method m_toString =
                Object.class.getMethod(
                        "toString",
                        new Class[0]
                );


        private static Method m_equals =
                Object.class.getMethod(
                        "equals",
                        new Class[] { Object.class }
                );


        public final void defer(Person p, String s)
                throws CannotDeferException
        {
                try
                {
                        h.invoke(
                                this,
                                m_defer,
                                new Object[] { p, s } );
                }
                catch( Error err ) { throw err }
                catch( RuntimeException rte ) { throw rte; }
                catch( CannotDeferException cde ) { throw cde; }
                catch( Throwable t )
                {
                        throw new UndeclaredThrowableException( t );
                }
        }


        public final void escalate(Person p, int i)
        {
                try
                {
                        h.invoke(
                                this,
                                m_escalate,
                                new Object[] { p, new Integer( i ) } );
                }
                catch( Error err ) { throw err; }
                catch( RuntimeException rte ) { throw rte; }
                catch( Throwable t )
                {
                        throw new UndeclaredThrowableException( t );
                }
        }


        public final int hashCode()
        {
                try
                {
                        return (
                                (Integer) h.invoke(
                                        this,
                                        m_hashCode,
                                        null )
                        ).intValue();
                }
                catch( Error err ) { throw err; }
                catch( RuntimeException rte ) { throw rte; }
                catch( Throwable t )
                {
                        throw new UndeclaredThrowableException( t );
                }
        }


        public final String toString()
        {
                try
                {
                        return (String)
                                h.invoke( this, m_toString, null );
                }
                catch( Error err ) { throw err; }
                catch( RuntimeException rte ) { throw rte; }
                catch( Throwable t )
                {
                        throw new UndeclaredThrowableException( t );
                }
        }


        public final boolean equals(Object o)
        {
                try
                {
                        return (
                                (Boolean) h.invoke(
                                        this,
                                        m_equals,
                                        new Object[] { o } )
                        ).booleanValue();
                }
                catch( Error err ) { throw err; }
                catch( RuntimeException rte ) { throw rte; }
                catch( Throwable t )
                {
                        throw new UndeclaredThrowableException( t );
                }
        }


        public final int getPriority(Person p)
        {
                try
                {
                        return (
                                 (Integer) h.invoke(
                                        this,
                                        m_getPriority,
                                        new Object[] { p } )
                        ).intValue();
                }
                catch( Error err ) { throw err; }
                catch( RuntimeException rte ) { throw rte; }
                catch( Throwable t )
                {
                        throw new UndeclaredThrowableException( t );
                }
        }


        public final void resolve(Person p, String s)
        {
                try
                {
                        h.invoke(
                                this,
                                m_resolve,
                                new Object[] { p, s }
                        );
                }
                catch( Error err ) { throw err; }
                catch( RuntimeException rte ) { throw rte; }
                catch( Throwable t )
                {
                        throw new UndeclaredThrowableException( t );
                }
        }
}

  
 
 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.