Re: New Reflection/Beans API
"Stephen Colebourne" <[email protected]>
| Newsgroups | gmane.comp.jakarta.bcel.devel |
|---|---|
| Message-ID | <005801c20b4b$c8e68b00$364e18d4@oemcomputer> |
Hi, I haven't done too badly so far and now have a basic working generator. It generates a bean's get, set and property methods from an interface. It also generates the property accessors by creating a class per property (as I think is the Java 1.4 way). However I have a question about the Class class. This class appears to require quite a lot of setting up to create an instance. Is there any factory method that I've missed to create instances of a Class? Stephen From: Juozas Baliuka <[email protected]> > Hi, > It must be trivial to introduce "Bean" interface and as I understand you > don't need > to generate "Property" interface, it can be implemented usual way. > I can implement this stuff, if you need my help. > > At 15:57 2002.06.03 +0100, you wrote: > >Hi, > >Well, you'll never guess what I've been working on today... > > > >My interest in this comes from the Joda project (www.joda.org). There I am > >developing code which aims to build upon the current JavaBean spec and to > >provide more functionality. Already working are Java (non-BCEL) versions of > >an API. However, there are places where it is slow, and it is memory hungry. > >This is where I have started to use BCEL (I've only started today, so I > >haven't got too far yet). > > > >The API includes a Bean interface which is to be implemented by all beans. > >This provides access to each property of the bean: > >interface Bean { > > Map getPropertyMap(); > > Property getProperty(String propertyName); > > Class getBeanType(); > > Object cloneDeep(); > >} > >interface Property { > > void set(Object object); > > Object toObject(); > > boolean isReadOnly(); > > boolean isModifiable(); > > void setReadOnly(); > > void setModifiable(boolean); > > String getPropertyName(); > > Class getPropertyType(); > > String getContentName(); > > Class getContentType(); > > boolean equalsValue(Object object) > > void addPropertyChangeListener(PropertyChangeListener) > > void removePropertyChangeListener(PropertyChangeListener) > > void firePropertyChange(Object from, Object to) > >} > > > > > Possible features: > > > ------------------ > > > * Property objects (i.e. bound to a particular object field) > > > * Read-only properties > > > * Automagically generated setters, getters, event methods, etc. > > > * Generate BeanInfo's for Introspection > > > * Generate Beans for alternate sources (XML, DB tables) > > > * Collection handling > > > >I agree with most of these. BeanInfo is more trouble than its worth. XML/DB > >can build upon the architecture rather than needing to be BCELed in at a low > >level. I would also add > >* Allow properties to be added by applications on demand > >* Generate from an interface, abstract class or real class > > > >For interfaces and abstract methods, things are easy - just generate code > >according to some default setup. But a factory is required to actually > >create the objects - and people hate factories (and beans really should have > >a no-args public constructor) > > > > I hate a no-args public constructor in mutable classes :). > The main problem will be to implement Serialization for classes generated > at runtime. > > > > > > > >Thus a normal class would need to be modified on load. My thought was that > >any options could be set as API calls with the method being replaced. > >public void setSurname(String surname) { > > // some application logic > > BeanGen.createSet(flags); > > // some application logic > >} > > > >Well, thats what I'm looking at anyway ;-) > > > > It is no meaning to implement Reflection, if it doe's the same as > java.lang.reflect.*, It has some meaning > for jdk1.3 (performance), but this code will depend on jdk1.3 version > support time. > I tested performance on jdk1.4 and it is the same for generated classes and > JAVA reflection, you can > find some trivial experiment on this list. > > > >Reflection > >---------- > >I'm more interested in the Beans side, but... > > > >For statics, isn't it a case of passing null in where the object ref would > >go? That's what Java reflction does. > > > >Stephen > > > >----- Original Message ----- > >From: Markus Dahm <[email protected]> > >To: <[email protected]> > >Sent: Monday, June 03, 2002 3:27 PM > >Subject: New Reflection/Beans API > > > > > > > Hi, > > > > > > recently there has been some discussion about how to design/implement > > > an Reflection and Bean API using BCEL. Since I think it would be a > > > very good idea to have such a thing in BCEL, I'd like to start a > > > discussion here about the requirements and implementation issues. > > > > > > This is not a real proposal, just a collection of thoughts and ideas > > > where I took some from a previous posting by Stephen Colebourne. > > > > > > Reflection: > > > ----------- > > > > > > How it should work is obvious (!?), we add some code to the class that > > > is to used be used reflectively. We could do this statically, i.e., in > > > some kind of compiler, or using a class loader, which may be a little > > > less performant, but is of course much more flexible. > > > > > > The benefits of such an API would be > > > > > > a) increased performance of reflection (measurements?) > > > > > > b) additional features possible, e.g., we could have a class loader > > > that allows to run a chain of class modifiers, where adding reflexive > > > behaviour would be just one. I.e., such class modifiers would have a > > > method > > > > > > public JavaClass modifyClass(JavaClass clazz) { ... } > > > > > > c) base for a Beans API > > > > > > The question is how to tell which classes need to be augmented. This > > > has to be know statically since we only have one chance to augment the > > > class, namely when it is loaded/created. The simpliest approach would > > > be to require the class to implement a marker interface, say > > > > > > public interface Reflective {} > > > > > > The other possibility would be to tell the class loader, before the > > > class gets loaded, e.g., via some regular expression: > > > > > > cl.addReflectiveClass("com.foo.beans.*Impl"); > > > > > > One could also restrict access to certain methods and fields. > > > > > > -------------------------------------------------------------------------- > >------ > > > > > > Given that we want to modify class A > > > > > > public class A implements Reflective { > > > private String str; > > > private int x; > > > > > > int foo() { } > > > int foo(int x) { } > > > } > > > > > > We would then like to use reflection like this: > > > > > > A a = new A(); > > > JavaClass clazz = Repository.lookupClass("A"); > > > Field[] fields = clazz.getFields(); > > > Method[] methods = clazz.getMethods(); > > > > > > fields[0].setValue(a, "Hello world"); > > > Object result = methods[i].invoke(a, new Object[] { new > > > Integer(4711); }); > > > > > > Of course setValue/invoke would throw an exception if the passed > > > object does not support our kind of reflection. > > > > > > public void setValue(Object target, Object value) throws SomeException > >{ > > > if(target instanceof BCELReflective) { > > > ((BCELReflective)target).BCELsetValue(target, field_name, value); > > > } else if(target == null) { // Access to static field > > > ?????????????? > > > } > > > } > > > > > > However, we have our first problem here: How does this work for static > > > fields and methods? > > > > > > > > > As you probably already noticed the class loader or whatever would let A > > > implement another interface and implement its methods: > > > > > > public interface BCELReflective { > > > public void BCELsetValue(String name, Object value); > > > public Object BCELgetValue(String name); > > > public Object BCELinvoke(String name, Object[] args); > > > } > > > > > > These methods would wrap/unwrap the arguments and call the > > > corresponding methods or set/get the right field. > > > > > > > > > Problems so far: > > > --------------- > > > > > > * As we all know methods may be overloaded thus just using the name is > > > not really sufficient here, instead we could use the method index or > > > some generated identifier. Using the index would allow us to use a > > > fast switch() statement. > > > > > > * Fields and methods currently do not know their index nor the > > > JavaClass object they belong to. We could pass them in the > > > setValue/invoke argument list. > > > > > > * How do we implement reflection for static fields and methods? > > > > > > > > > > > > Beans (Really just a scratch file of ideas): > > > ------------------------------------------- > > > > > > I'm not an expert on Java Beans, but probably many of you are... > > > > > > What we could have is an extension of ClassGen, say BeanGen that has > > > additional methods and an extended InstructionFactory. I know there > > > is a class somewhere the Java Bean API such as "BeanAdapter" which > > > already implements the default behaviour and can be used as a > > > delegatee. I.e., we can use this class in our API. > > > > > > What we obviously need is a declarative way to tell which features > > > we want for our bean. Having an interface with empty methods is a > > > very simple approach, but I think we need something more powerful. > > > One problem is for example that property names need not to be > > > equivalent to field names. Getters and setters may have additional > > > checking code that relies on other fields. > > > > > > Possible features: > > > ------------------ > > > * Property objects (i.e. bound to a particular object field) > > > * Read-only properties > > > * Automagically generated setters, getters, event methods, etc. > > > * Generate BeanInfo's for Introspection > > > * Generate Beans for alternate sources (XML, DB tables) > > > * Collection handling > > > * See below :) > > > > > > Cheers > > > Markus > > > > > > P.S. The developer list is being archived now. > > > > > > -------------------------------------------------------------------------- > >----- > > > The original positing from Stephen Colebourne > > > > > > > > > Scope: > > > Reflection - Class, Method, Field, ... > > > Bean - Introspector, javabeans > > > > > > Need: > > > - Performance on java1.3 and earlier > > > - J2ME > > > - Current reliance on javabean spec version 1 that was designed to replace > > > ActiveX, not be a domain model. > > > - Boring coding of javabean gets/sets (I know tools can help, but I still > > > see bugs in gets and sets) > > > - Auto generated event methods (bound/constrained properties) > > > - Desire for dynamicly created javabeans/ properties (from databases, xml > > > etc.) > > > - Desire to pass around an object representing a property > > > - Desire to change the bean Introspector's lookup mechanism, such as to > > > allow private get/set methods to be treated as properties > > > - Desire to handle collections properly (they aren't handled at all by > >beans > > > Introspector at the moment > > > - Desire to dynamically make a property read only once setup (like const > >in > > > C) > > > > > > Bean types: > > > - Coder writes interface with coded get and set methods, BCEL generates > > > implementation on the fly > > > - Coder writes abstract class with coded get and set methods, BCEL > >generates > > > implementation on the fly > > > - Coder writes real class with coded get and set methods, BCEL modifies > > > parts on the fly > > > - A general purpose bean, to be used where all the data is dynamic, > >similar > > > to a HashMap > > > - A mixture object, where some fields have coded get and set methods, > >others > > > are dynamically created as the application requires > > > > > > > > > OK, so if you haven't guessed, I'm more interested in Beans than > >Reflection > > > on its own (Reflection is fine and useful, but its very low level). Most > >of > > > these ideas come from the Joda project, but I think they represent a good > > > idea of what people are using beans for now. > > > > > > Stephen > > > > > > > > > -- > > > 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]> > >