Ok, that was alot of fun, this package will definitly do what I need it to! Here's my experiment classes if your interested.

thanks for the help Juozas and Andreas,
Mark


Juozas Baliuka wrote:

use "Method.setAccessible(true)"
sample can be faund in this code:
http://cglib.sourceforge.net/xref/net/sf/cglib/CodeGenerator.html#166

----- Original Message -----
From: "Mark R. Diggory" <[EMAIL PROTECTED]>
To: "BCEL Users List" <[EMAIL PROTECTED]>
Sent: Friday, January 17, 2003 8:51 PM
Subject: Re: How to get instance of my new Class.



Thank you for the info, however, I'm slightly confused,
ClassLoader.defineClass(...) seems to be protected in both
java.lang.ClassLoader and org.apache.bcel.util.ClassLoader. Is there a
chance theres a decent example you could point me at in the bcel library
examples to outline how to do this.

-Mark


Juozas Baliuka wrote:


use ClassLoader.defineClass( byte[], int, int)

----- Original Message -----
From: "Mark R. Diggory" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Friday, January 17, 2003 8:17 PM
Subject: How to get instance of my new Class.





I've written code using the BCEL packages that produces a new Class.

I can see how to get the byte code or source of the be class and save it
a file from the examples provided, however, I don't really want to do
this yet. I'd like to jusat create a new instance of my class I've
created in the current process in which I generatede it. Does anyone
have suggestions on how I can do this?

thanks,
Mark


--
To unsubscribe, e-mail:



<mailto:[EMAIL PROTECTED]>



For additional commands, e-mail:



<mailto:[EMAIL PROTECTED]>




--
To unsubscribe, e-mail:

<mailto:[EMAIL PROTECTED]>

For additional commands, e-mail:

<mailto:[EMAIL PROTECTED]>



--
To unsubscribe, e-mail:

<mailto:[EMAIL PROTECTED]>

For additional commands, e-mail:

<mailto:[EMAIL PROTECTED]>



--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>



/*
 * TestBean.java
 *
 * Created on January 17, 2003, 11:38 AM
 */

package org.mrd.test;

/**
 *
 * @author  Administrator
 */
public class TestBean {
    
    /** Holds value of property marksProperty. */
    private String marksProperty;
    
    /** Holds value of property anotherProperty. */
    private double anotherProperty;
    
    /** Getter for property marksProperty.
     * @return Value of property marksProperty.
     */
    public String getMarksProperty() {
        return this.marksProperty;
    }
    
    /** Setter for property marksProperty.
     * @param marksProperty New value of property marksProperty.
     */
    public void setMarksProperty(String marksProperty) {
        this.marksProperty = marksProperty;
    }
    
    /** Getter for property anotherProperty.
     * @return Value of property anotherProperty.
     */
    public double getAnotherProperty() {
        return this.anotherProperty;
    }
    
    /** Setter for property anotherProperty.
     * @param anotherProperty New value of property anotherProperty.
     */
    public void setAnotherProperty(double anotherProperty) {
        this.anotherProperty = anotherProperty;
    }
    
}
/*
 * Beanextender.java
 *
 * Created on January 17, 2003, 11:51 AM
 */

package org.mrd.test;

import org.apache.bcel.util.*;
import org.apache.bcel.generic.*;
import org.apache.bcel.classfile.*;
import org.apache.bcel.*;
import java.io.*;

import java.lang.reflect.*;
import java.security.PrivilegedAction;
import java.util.*;

/**
 *
 * @author  Administrator
 */
public class BeanExtender implements Constants{
    
    public static final int READ_ONLY = 0;
    
    public static final int WRITE_ONLY = 1;
    
    public static final int READ_WRITE = 2;
    
    private InstructionFactory _factory;
    
    private ConstantPoolGen    _cp;
    
    private ClassGen           _cg;
    
    /** Holds value of property className. */
    private String className;
    
    /** Holds value of property packageName. */
    private String packageName;
    
    
    private String canonicalName;
    
    /** Holds value of property baseClass. */
    private Class baseClass;
    
    /** Creates a new instance of Beanextender */
    public BeanExtender(Class baseClass, String className, String packageName) {
        this.baseClass = baseClass;
        this.className = className;
        this.packageName = packageName;
        this.canonicalName = packageName+"."+className;
        
        _cg = new ClassGen(canonicalName , baseClass.getName() , className + ".java", 
ACC_PUBLIC | ACC_SUPER, new String[] {  });
        _cp = _cg.getConstantPool();
        _factory = new InstructionFactory(_cg, _cp);
        
        createDefaultConstructor();
    }
    
    public void addProperty(java.lang.String name, Type type, int accessibility) {
        
        createField(type,name);
        
        switch(accessibility){
            case READ_ONLY : {
                createGetterMethod(type,name);
                break;
            }
            case WRITE_ONLY : {
                createSetterMethod(type,name);
                break;
            }
            default : {
                createGetterMethod(type,name);
                createSetterMethod(type,name);
            }
        }
    }
    
    private void createDefaultConstructor() {
        InstructionList il = new InstructionList();
        MethodGen method = new MethodGen(ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new 
String[] {  }, "<init>", canonicalName, il, _cp);
        InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
        il.append(_factory.createInvoke(baseClass.getName(), "<init>", Type.VOID, 
Type.NO_ARGS, Constants.INVOKESPECIAL));
        InstructionHandle ih_4 = il.append(_factory.createReturn(Type.VOID));
        method.setMaxStack();
        method.setMaxLocals();
        _cg.addMethod(method.getMethod());
        il.dispose();
    }
    
    
    private void createField(Type type, String propertyName) {
        FieldGen field;
        field = new FieldGen(ACC_PRIVATE, type, propertyName, _cp);
        _cg.addField(field.getField());
    }
    
    private void createGetterMethod(Type type, String propertyName) {
        String methodName = "get" + propertyName.substring(0,1).toUpperCase() + 
propertyName.substring(1);
        
        InstructionList il = new InstructionList();
        MethodGen method = new MethodGen(ACC_PUBLIC, type, Type.NO_ARGS, new String[] 
{  }, methodName, canonicalName, il, _cp);
        InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
        il.append(_factory.createFieldAccess(canonicalName, propertyName, type, 
Constants.GETFIELD));
        InstructionHandle ih_4 = il.append(_factory.createReturn(Type.OBJECT));
        method.setMaxStack();
        method.setMaxLocals();
        _cg.addMethod(method.getMethod());
        il.dispose();
    }
    
    private void createSetterMethod(Type type, String propertyName) {
        String methodName = "set" + propertyName.substring(0,1).toUpperCase() + 
propertyName.substring(1);
        
        InstructionList il = new InstructionList();
        MethodGen method = new MethodGen(ACC_PUBLIC, Type.VOID, new Type[] { type }, 
new String[] { "arg0" }, methodName, canonicalName, il, _cp);
        InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
        il.append(_factory.createLoad(Type.OBJECT, 1));
        il.append(_factory.createFieldAccess(canonicalName, propertyName, type, 
Constants.PUTFIELD));
        InstructionHandle ih_5 = il.append(_factory.createReturn(Type.VOID));
        method.setMaxStack();
        method.setMaxLocals();
        _cg.addMethod(method.getMethod());
        il.dispose();
    }
    
    public Object newInstance()
    throws  java.lang.ClassNotFoundException,
    java.lang.NoSuchMethodException,
    java.lang.IllegalAccessException,
    java.lang.InstantiationException,
    java.lang.reflect.InvocationTargetException {
        
        
        byte[] bytes = this.getJavaClass().getBytes();
        
        java.lang.ClassLoader loader = java.lang.ClassLoader.getSystemClassLoader();
        Class cls = Class.forName("java.lang.ClassLoader");
        
        java.lang.reflect.Method method = cls.getDeclaredMethod(
        "defineClass",
        new Class[]{ String.class, byte[].class, int.class, int.class }
        );
        
        // protected method invocaton
        method.setAccessible(true);
        
        SecurityManager sm = System.getSecurityManager();
        if ( sm != null  ) {
            sm.checkPermission(new RuntimePermission("defineCGLIBClassInJavaPackage"));
        }
        
        //way depricated in jdk to define classes,
        // doe's not throws SecurityException if class name starts with "java."
        Object[] args2 = new Object[]{this.canonicalName ,bytes ,new Integer(0), new 
Integer(bytes.length) };
        Class result = (Class)method.invoke(loader, args2);
        method.setAccessible(false);
        
        return result.newInstance();
        
    }
    
    /** Getter for property className.
     * @return Value of property className.
     */
    public String getClassName() {
        return this.className;
    }
    
    /** Getter for property packageName.
     * @return Value of property packageName.
     */
    public String getPackageName() {
        return this.packageName;
    }
    
    /** Getter for property baseClass.
     * @return Value of property baseClass.
     */
    public Class getBaseClass() {
        return this.baseClass;
    }
    
    /** Getter for property javaClass.
     * @return Value of property javaClass.
     */
    public JavaClass getJavaClass() {
        return _cg.getJavaClass();
    }
    
    public static void main(String[] args) throws Exception {
        
        org.mrd.test.BeanExtender extender = new 
org.mrd.test.BeanExtender(org.mrd.test.TestBean.class, "NewTestBean", "org.mrd.test");
        
        extender.addProperty("testProperty",Type.STRING,BeanExtender.READ_WRITE);
        
        
        TestBean test = (TestBean)extender.newInstance();
        
        test.setAnotherProperty(1.0);
        test.setMarksProperty("This is a test");
        
        System.out.println(test.getAnotherProperty());
        System.out.println(test.getMarksProperty());
        
        
        java.beans.BeanInfo info = 
java.beans.Introspector.getBeanInfo(test.getClass());
        
        java.beans.PropertyDescriptor[] props = info.getPropertyDescriptors();
        
        for(int i = 0; i < props.length; i++){
            System.out.println("Bean Property: "+props[i].getName());
            
            if(props[i].getName().equals("testProperty")){
                System.out.println("Value Before: " + 
props[i].getReadMethod().invoke(test, new Object[]{ }));
                
                if(props[i].getWriteMethod() != null)
                    props[i].getWriteMethod().invoke(test,new Object[]{"This is a 
test"});
                    
                    
                System.out.println("Value After: " + 
props[i].getReadMethod().invoke(test, new Object[]{ }));
            }
        }
        
    }
}
--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to