GWT Reflection - Overview

GWT Reflection is a small framework which give you ability to use reflection API on client side (yes! on browse side!) of application. Google Web Toolkit obfuscate JavaScript so it is not readable for application in execution time. So.. it is hard to use any kind of reflection on browser side of application. To make JavaScript reflectable we must create some helper that could memorize class description in compilation time. This description will later (in runtime) help us to manipulate classes, even after obfuscate.

GWT Reflection are composed of two component GWT Reflection Wrapper and GWT Reflection Description Generator.

GWT Reflection Wrapper - provides basic functionality for Java 1.4 reflection API, we use this component on client side.
GWT Reflection Description Generator - provides simple tool (you can use it as ANT task) which create helpers for GWT Reflection Wrapper. This description will by used in runtime of application to manipulate your application classes.

To make it more clear let's look at a first example. (Quick start)
Quick start
First of all you should download:

GWT Reflection Wrapper
GWT Reflection Description Generator
GWT Reflection Hello World - sources for following example
Step 1. Let's create new project in eclipse, name it 'gwtreflect-helloworld'.
Using gwt tool create project

./projectCreator 
	-eclipse gwtreflect-helloworld 
	-ant gwtreflect-helloworld 
	-out ~/workspace/java-eclipse/gwtreflect-helloworld 
	-overwrite	

and create new application

./applicationCreator 
	-eclipse gwtreflect-helloworld 
	-out ~/workspace/java-eclipse/gwtreflect-helloworld 
	pl.rmalinowski.gwtreflect.helloworld.client.GWTRHelloWorld

Now add new library to project (Eclipse menu-> Project propertis -> java build files -> librarys -> Add Jar -> gwtreflect.jar
Step 2. Create new package 'pl.rmalinowski.gwtreflect.helloworld.client.someclasses' and add new classes in here. We will use reflection API on this class. This class will implements Reflectable interface. We use Reflectable interface like IsSerializable, to show that we want to memorize class description for future use (see Step 4). In future you will see that you dont need to implements Reflectable interface, but for now it is easest way.

package pl.rmalinowski.gwtreflect.helloworld.client.someclasses;

import pl.rmalinowski.gwtreflect.client.reflect.Reflectable;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;

public class MyClass implements Reflectable {

    private Integer value;

    public MyClass () {

    }

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

    public String showValue() {
        String msg = "Value = " + value;
        Window.alert(msg);
        GWT.log("Alert shown (" + msg +")", null);
        return msg;
    }

}

Step 3. Next step is to package our classes to JAR file. If you created project using -ant option you should have file in your project root folder looking like this:


<?xml version="1.0" encoding="utf-8" ?>
<project name="gwtreflect-helloworld" 
	default="compile" 
	basedir=".">

<!-- set classpath -->
  <path id="project.class.path">
    <pathelement path="${java.class.path}/"/>
    <pathelement path="/opt/gwt/gwt-user.jar"/>
    <!-- Additional dependencies (such as junit) go here -->
  </path>

  <target name="compile" 
	description="Compile src to bin">

    <mkdir dir="bin"/>
    <javac srcdir="src:test" 
		destdir="bin" includes="**" 
		debug="on" debuglevel="lines,vars,source" 
		source="1.4">
      <classpath refid="project.class.path"/>
    </javac>
  </target>

  <target name="package" 
	depends="compile" 
	description="Package up the project as a jar">

    <jar destfile="gwtreflect-helloworld.jar">
      <fileset dir="bin">
        <include name="**/*.class"/>
      </fileset>
      <!-- Get everything; source, modules, html files -->
      <fileset dir="src">
        <include name="**"/>
      </fileset>
      <fileset dir="test">
        <include name="**"/>
      </fileset>
    </jar>
  </target>

  <target name="clean">
    <!-- Delete the bin directory tree -->
    <delete file="gwtreflect-helloworld.jar"/>
    <delete>
      <fileset dir="bin" includes="**/*.class"/>
    </delete>
  </target>

  <target name="all" depends="package"/>

</project>


Only what you must do is to run 'compile' and 'package' tasks.
Step 4. Now, when we have gwtreflect-helloworld.jar we must generate description for our class. We will use GWT Reflection Description Generator. You can execute this tool from command line, but we will use ant task for do that. Ant task definition and execution code should look like this:

<?xml version="1.0" encoding="UTF-8"?>
<project default="generate-gwtreflect" basedir=".">

	<property name="path.gwtReflectDescGenerator" 
		value="/home/rmalinowski/opt/gwtreflect"/>

	<property name="path.jar.gwtReflectWrapper" 
		value="../gwtreflect/dist/gwtreflect.jar"/>

	<property name="path.helloWorldProj" 
		value="../gwtreflect-helloworld"/>

	
	 <path id="lib.path">
	<fileset dir="${path.gwtReflectDescGenerator}/lib" 
		includes="*.jar"/>
	<fileset dir="${path.gwtReflectDescGenerator}" 
		includes="*.jar"/>
	 </path>
	
	<taskdef name="gwtreflect" 
		classname="pl.rmalinowski.gwtreflect.ant.GWTReflect"
		classpathref="lib.path"
	/>
	
	<target name="generate-gwtreflect">
	<gwtreflect 
		outdir="${path.helloWorldProj}/src" 
		source="${path.helloWorldProj}/gwtreflect-helloworld.jar;
${path.jar.gwtReflectWrapper}" 
		packagein="pl.rmalinowski
.gwtreflect.helloworld.client.someclasses"
		packageout="pl.rmalinowski
.gwtreflect.helloworld.client.gwtr"
		>
		
		
		</gwtreflect>
	</target>
</project>


Run task 'generate-gwtreflect' and refresh project folder in Eclipse IDE.
Step 5. After refresh you should see new package pl.rmalinowski.gwtreflect.helloworld.client.gwtr in your project. In this package you will see :
ClassRegistrator - which are used to make sure that GWT will generate and package your classes to client runtime eviroment.

MyClass__GWTR - where are description for our class MyClass. (see Step 2)

And now you can use reflection API in your browser. Lets extends method onModuleLoad our GWTRHelloWorld class to run and see how it works:
package pl.rmalinowski.gwtreflect.helloworld.client;

import pl.rmalinowski.gwtreflect.client.reflect.Class;
import pl.rmalinowski.gwtreflect.client.reflect.Method;
import pl.rmalinowski.gwtreflect
.client.reflect.NoSuchMethodException;
import pl.rmalinowski.gwtreflect
.helloworld.client.someclasses.MyClass;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;

/**
 * Entry point classes define onModuleLoad().
 */
public class GWTRHelloWorld implements EntryPoint {

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {

		pl.rmalinowski.gwtreflect.helloworld
.client.gwtr.ClassRegistrator.registerAll();

		Class c = null;
		c = Class.forName("pl.rmalinowski
.gwtreflect.helloworld.client.someclasses.MyClass");

		// or
		c = Class.forName(MyClass.class.toString());
		// or
		c = Class.getClass(MyClass.class);
		
		MyClass obj = (MyClass) c.newInstance();
	    
		Method setValue = null;
		
		try {
            setValue = c.getMethod("setValue", 
		new java.lang.Class[]{Integer.class});

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        setValue.invoke(obj, new Object[]{new Integer(123)});
        
        GWT.log("After setValue invoced, 
		obj.getValue() = "+obj.getValue(), null); 
        

        Method showValue = null;
        try {
            showValue = c.getMethod("showValue", 
			new java.lang.Class[]{});

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        String retStr = (String) showValue.invoke(obj, null);
        GWT.log("After showValue invoced, retStr = "+retStr, null); 
		
	}
}


Run project and see what happen next :).
Extended Futures
Description of more extanded futures will be soon...
Road Map
This is only beginning of possibilities what have or will have GWT Reflection. First of all there are somu undocumented option and futures. So in the near future I will try to document it. Next I will try to provide in GWT Reflection full compatibility with Java 1.4 reflection API (for now it is approximately 70% of compatibility). And after that and some interest from GWT Community maybe it will be time for some more.
Text me!
If you have any question text me.



Download
Current Releases
GWT Reflection ver-0.7.0 [ download ]
Examples
GWT Reflection Hello World [ download ]

About me
rmalinowski.pl - my home page [ visit ]

My other projects
Sock 4 Log is a java listening tool, created to make remote logging simpler. It's created for retrieving xml log data from Flash, PHP, JavaScript and other....   [ more ]

GWT 2 SWF intend to provide software bridge between GWT and FLASH/FLEX. It's made for communication between GWT and FLASH/FLEX   [ more ]

ASIoC is a very simple implementation of Dependency Injection (DI) pattern also known as Inversion of Control (IoC) written in Action Script 2.0.    [ more ]


 
SourceForge.net Logo