Dynamically create classes in Java - java

I would like to create a class in Java based on the fields defined in my XML config file:
For example: if the XML file contains (the syntax has been maligned for posting):
<property name="agent_host"></property>
<property name="subsystem"></property>
then internally it will create a class Event such as Event(String agentHost, String subSystem) that the client can instantiate. Note: the client always knows that this class will be called "Event" but does not know how many "mandatory parameters" it needs to pass.
On the other hand if I have a XML file with:
<property name="agent_host"></property>
then it will create Event(String eventHost) that the client can use for instantiation.

Yes, you could use reflection, but what comes to my mind is working with a class that you could add property.
Imagine a class that has one encapsulated HashMap using a String as a key (for the attribute name) and the value of the attribute so you could read the XML file and for evey property add the attribute to the class like.
For this line:
<property name="subsystem" type="String">value123</property>
GenericClass c = new GenericClass();
c.addAttribute("subsystem", new String("value123"));
//and you could implement a get and set methods like this:
public String getAttributeValue(String attributeName)
{
return internalHashMap.get(attributeName).toString();
}
Using this you could also implement a setAttributeValue
will be quite simple I think

If you really interested in creating a class dynamically, try Byte code Enhancement libraries like BCEL from Apache.

This isn't really a class you want, it's data. Why not use a hashmap? I really dislike "Bean" style classes--they encourage bad coding (there is no place in a generated class to put actual code, so everything ends up being manipulated by external code anyway).
You can just load a hashmap from your XML and inject it into a real object--that way you don't have to worry about actually passing a hash around, you are passing a real object with real business methods and real type safety--it just HAPPENS to use a hashmap internally to store data instead of member variables.
I've done a lot more than this, but at some point you realize Hibernate does everything you want for you.

I think the DynaBean from Commons-BeanUtils may be what you're looking for.
A DynaBean is a Java object that supports properties whose names and data types, as well as values, may be dynamically modified. To the maximum degree feasible, other components of the BeanUtils package will recognize such beans and treat them as standard JavaBeans for the purpose of retrieving and setting property values.

Related

Am I abusing/misusing Java reflection?

I'm writing a program to read data from a file, which may be in one of several format (different versions of the same format, actually) and I'm using reflection for calling the appropriate function for each format. Assuming that file format is a number specified on the first byte of the file:
Class DataFile extends Model {
...
Blob file
...
public void parse() throws Exception{
InputStream is = file.get();
Class c = Class.forName("models.DataFile");
Method m = c.getMethod("parse_v"+is.read(), (Class []) null);
m.invoke(this, (Object []) null);
}
public void parse_v0() throws Exception{
...
}
public void parse_v1() throws Exception{
...
}
}
My question is, am I abusing/misusing reflection? I have the feeling that I should be using inheritance and create a different class for each file type with its own "parse" procedure, but I don't know the file type until I start parsing... and then I cannot "downcast" and just use something like ((DataFile_v1) this).parse() so I am a little lost.
Thank you for your time!
There's nothing fundamentally wrong with this, but a more flexible and extensible way to do the same thing would be to use the version information as a key in a Map, and have the values in the Map be handler objects. Then any code can register a handler (the handlers can all implement a common interface) and your reader code can just look up the handler in the Map and invoke it.
Be sure to handle the case where the Map doesn't include a handler for a particular version!
If you make a DataFile interface define a parse method, and implement the interface with multiple classes (DataFile_v1, etc.), then the calling code doesn't have to know which implementation was chosen.
DataFile dataFile = dataFileFactory.getForVersion(is.read());
dataFile.parse(file);
I'd argue that this is a better approach from a general design perspective. However, at some point you will need to create some kind of mapping between the version number and the DataFile implementations. (In this case I'm doing it in an imaginary dataFileFactory.) You'll have to determine whether it would be more appropriate to select an implementation using reflection or some other method.
I think it's OK to use reflection here. The alternative would be using inheritance or an enum (i.e. the Strategy pattern), and a map from the version code to the proper Strategy. Once you have initialized all the desired mappings, you just get the right parser object from the map and invoke it. However, setting up this solution still requires a significant amount of boilerplate code, which diminishes its readability.
What you're doing isn't bad. If you want to have the different parsers in different classes, you can't downcast as you say, but you could instantiate a new parser object. So your existing class would be a facade in front of the actual parsers which aren't instantiated until you know which format you're parsing.
You can use a collection, but using reflections is looking up a collection as well. Provided your mapping doesn't change I would use reflections.
getClass().getMethod("parse_v"+is.read()).invoke(this);

Copy of the internal data structure of a class

Out of curiosity, I'd like to know if any class exists in Java with a method that returns a copy of its data structure. I ask because in class the teacher said a method like this breaks privacy, but I think that getting a copy of the structure is useful if you want to rearrange the structure. I'd like an example. Thanks.
I'm not entirely sure what you mean by the "data structure" of a class, but assuming you mean the members it contains, what you're looking for is reflection.
Try this tutorial.
Maybe you are missing the point: If you build a class which encapsulates some kind of internal data then you should NOT add a method which returns the internal data structure, but only the data that is encapsulated.
(Which is kind of the idea of encapsulation)
There should not be any need to "rearrange" your internal representation from the outside - because it is supposed to be internal and thus transparent in its use. (Meaning: You should not even be able to say what kind of data structure is used)
If you serialize it, any object (that is serializable) will happily prints its internal structure to a binary stream. And yes, this breaks encapsulation.
And yes, no one stops you from going to change the binary output and read it in again to create an altered object.
NB: there are more strange issues regarding serialization. For example, when deserializing objects new objects are created without their constructor ever being called. Et cetera. Serialization of objects is the maybe least object-oriented thing one can do with objects.
You're mixing up some concepts here.
Classes really are "data structures + methods", so in general you'd need a class to represent your class. Hey, a nice custom-built one would be the class your data is already in. You may be thinking of a class as a collection of simple fields, but this is not always the case.
As others have mentioned, you can extract the data via reflection, e.g.
public Map<String,Object> fields() {
Map output=new hashMap<String,Object>();
for (Field f:getClass().getFields())
{
try{
output.put(f.getName(), f.get(this));
}
catch(... //IllegalArgument, IllegalAccess.. {... }
}
return output;
}
You can get into encapsulation issues here, in general the class should provide the data that you need to see from it, I tend to use things like this only for debugging.
I'm not sure what you mean by "rearrange the structure". The class generally represents the structure of the data. If there's a transformation you want to accomplish, it probably belongs in a class method, e.g. are you thinking of something like a co-ordinates class that can provide a transformed version of itself into polar co-ordinates?
A simple way to see the internal representation of an object is to serialise it using XStream. This will generate an XML representation of the class and its components (and so on).
Does this break encapsulation ? Yes - in the sense that you're able to inspect the internal structure of the class. You can take that XML, change it, and provided that it matches the .class structure that it came from, deserialise it back into a .class instance.

Inheritance with JAXB

I have an XSD file which is used to generate some objects which are then shared with other systems. I'd like to customize some of the business logic a bit in there by making some more specific implementation of these. I'm not adding new fields which need to be serialized, but more along the lines of adding setMethods which may take different format parameters. These methods do the work of translating the data into a form which is needed by the underlying object.
I may have a field on the JAXB object which is a string, but my system gives me an integer. So, I want to handle the work of converting that in a class which extends my base class.
So, is there anything special you need to do in order to get JAXB to look for XmlRootElement on a subclass of the object you are asking it to serialize? Or must I include a #XmlRootElement attribute on my more specific class?
thanks!
Yes, #XmlRootElement/ #XmlType should be enough. But why don't you just add these methods to the generated classes? (in case you are not regenerating them on each build, which is wrong imo)
However I'd advice externalizing the conversion to other (converter) classes / methods.

Java: What is the fastest way to inject fields using reflection?

Suppose, I have a lot of classes, which are constructed using Java reflection (for some reason). Now I need to post-inject values to fields, which are
annotated with #PostInject.
public class SomeClass {
#PostInject
private final String someString = null;
public void someMethod() {
// here, someString has a value.
}
}
My question is: what is a fast way to set a field using reflection?
Remember, I need to do this very often on a lot of classes, that's
why performance is relevant.
What I would do by intuition is shown by this pseudo-code:
get all fields of the class
clazz.getFields();
check, which are annotated with #PostInject
eachField.getAnnotation(PostInject.class);
make these fields accessible
eachAnnotatedField.setAccessible(true);
set them to a certain value
eachAnnotatedField.set(clazz, someValue);
I'm afraid that getting all fields is the slowest thing to do.
Can I someone get a field, when I know it from the beginning?
NOTE: I can't just let the classes implement some interface, which would
allow to set the fields using a method. I need POJOs.
NOTE2: Why I want post-field injection: From the point of view of an API user, it must be possible to use final fields. Furthermore, when the types and number of fields are not known by the API a priori, it is impossible to achieve field initialization using an interface.
NOTE2b: From the point of view of the user, the final contract is not broken. It stays final. First, a field gets initialized, then it can't be changed. By the way: there are a lot of APIs which use this concept, one of them is JAXB (part of the JDK).
How about doing steps 1 to 3 just after you constructed the object and saving the set of annotated fields that you obtain either in the object itself or by keeping a separate map of class to set-of-annotated-fields?
Then, when you need to update the injected fields in an object, retrieve the set from either the object or the seperate map and perform step 4.
Don't know if it's any good, but this project looks like it would do what you want. Quote:
A set of reflection utilities and
miscellaneous utilities related to
working with classes and their fields
with no dependencies which is
compatible with java 1.5 and generics.
The utilities cache reflection data
for high performance operation but
uses weak/soft caching to avoid
holding open ClassLoaders and causing
the caches to exist in memory
permanently. The ability to override
the caching mechanism with your own is
supported.
Another option, as you say you know the few fields concerned from the beginning, is to ask only for those fields or methods.
Example : see getDeclaredMethod or getDeclaredField in java/lang/Class.html
You can exploit existing frameworks that allow to inject dependencies on object construction. For example Spring allows to do that with aspectj weaving. The general idea is that you define bean dependencies at spring level and just mark target classes in order to advise their object creation. Actual dependency resolution logic is injected directly to the class byte-code (it's possible to use either compile- or load-time weaving).
Fastest way to do anything with reflection is to cache the actual Reflection API classes whenever possible. For example I very recently made a yet-another-dynamic-POJO-manipulator which I believe is one of those things everyone ends up doing at some point which enables me to do this:
Object o = ...
BeanPropertyController c = BeanPropertyController.of(o);
for (String propertyName : c.getPropertyNames()) {
if (c.access(propertyName) == null &&
c.typeOf(propertyName).equals(String.class)) {
c.mutate(propertyName, "");
}
}
The way it works is that it basically has that one controller object which lazyloads all the properties of the bean (note: some magic involved) and then reuses them as long as the actual controller object is alive. All I can say is that by just saving the Method objects themselves I managed to turn that thing into a damn fast thing and I'm quite proud of it and even considering releasing it assuming I can manage to sort out copyrights etc.

BeanUtils with an addXX method

I'm using the Apache BeanUtils setProperty method to import data from an Excel file in a generic manner. I provide the parser a list of "colum name" and "property name" pairs and then the parser sets the properties with setProperty( ..., "property name", ...) for the Excel fields that match with "column name". It's working nice but now I'm having a problem, I have a property that is setted with an addXXX() method and I cannot change that class.
How can I set this property without changing this class or the parser?
Is it possible?
Can I make something like a wrapper with DynaClass, PropertyUtils or MethodUtils so when setting that property it calls the addXX method?
Thanks!
You can write a decorator bean class that will wrap around your class and provide a setXXX() method delegating to addXXX() of the wrapped bean. You can even do that via dynamic proxy with help of cglib or any other bytecode instrumentation library.
If you'd rather go the DynaClass way, take a look at WrapDynaClass as a starting point. You'll have to extend it to provide custom PropertyDescriptor for your method. I wouldn't do this, though, for two reasons - first, addXXX() semantics is likely quite different from setXXX(); and secondly, the whole DynaClass/DynaBean internal API is a bit messy whereas writing your own decorator class is very straightforward.

Categories

Resources