Java Forum / General / July 2006
Flexible data transfer & manipulation
BogusException - 17 Jul 2006 00:42 GMT Given:
A class designed to:
1. Take an object in through one of its methods, 2. Read and add new attributes to that object, 3. Return this new object to the calling class.
This works fine as long as everything is known way ahead of time. Suppose, though, that the class does not always have the same object in, yet it just needs to find the object's attribute it needs? This is the problem, and I can't decide if there is a better way via XML or Java objects to do it.
If you've read this far, let me give you more detail:
I want to have a series of classes that do specific things to an object (could be an XML object, or...). Each class looks for something in particular in each data parcel and acts upon it. This could very well mean adding another "attribute", "element" or characteristic to the object, then passing it on its way. The classes are often in a different "order", so I can't code in every possible position in the line of processing classes.
With a rigid object structure, adding new attributes can't happen unless you know ahead of time the name and type of attribute. Could it be done with an array of objects? Probably, but that isn't a generic solution.
I thought about XML, and passing the schema for the XML document with the document itself but I can't seem to find a match for Java to do this with JAXP, JAXB, Dom or Sax. I don't want the data to ever be written to file-only transferred between classes (instantiated objects) at runtime in memory.
The data may have many occurances in a single XML doc/Java object, and the preference is toward speed-not toward random access.
Any ideas as to which Java solution is best for this kind of need?
TIA!
BogusException
Chris Smith - 17 Jul 2006 00:49 GMT > Given: > [quoted text clipped - 7 lines] > Suppose, though, that the class does not always have the same object > in, yet it just needs to find the object's attribute it needs? If you need to find and modify existing attributes of an object, then reflection does this. If you can afford to be a bit more limited (i.e., require that the objects being passed in implement the JavaBeans spec), then the java.beans.Introspector class is cleaner, and you can rely on the existing JavaBeans spec with which Java developers are quite familiar.
Later, though, you imply that you need to dynamically add or remove attributes from an object. That's not possible for an ordinary object. You should look into using an implementation of java.util.Map instead (the most common implementation is HashMap).
Finally, the most complex possible solution (well, almost) is to use a custom classloader to build an appropriate class based on your knowledge of the workflow at runtime. This is probably a horrible idea, but ask away if you decide you want to do it.
 Signature Chris Smith - Lead Software Developer / Technical Trainer MindIQ Corporation
BogusException - 17 Jul 2006 03:09 GMT > Later, though, you imply that you need to dynamically add or remove > attributes from an object. That's not possible for an ordinary object. > You should look into using an implementation of java.util.Map instead > (the most common implementation is HashMap). Chris,
An excellent suggestion. It looks like the 1.5 ConcurrentHashMap might just fit the bill. This brings me ot the next problem/situation I'm in as a result. The reason that the classes need to be able to accept an object that may have any number of attributes (or key/value pairs in Hashes) is because the order they are used in is not known until runtime, via a configuration file.
Remember how I said that the order of these utility classes is different each time? Well, this is because I want to write "modules" that can be arranged in a user-definable order. The problem is that the order that they will appear in-or whether they will appear at all-is not known at design time.
I'm looking for something I could have swore I read about a few months ago that describes a way to construct a class at runtime. Once the class is built (using a config), the class won't change for the lifetime of the program. It is impractical to try to write conditionals for every possibility there could be, never mind the insane overhead of doing so in practice.
Have you ever heard of such a critter?
TIA!
BogusException
Chris Smith - 17 Jul 2006 03:17 GMT > I'm looking for something I could have swore I read about a few months > ago that describes a way to construct a class at runtime. There are any number of such tools. The one I'm familiar with is Apache BCEL, but it has been a long time since I've used it and there may be better options around these days.
You should be aware, though, that there are serious limitations to doing this kind of thing. The standard advice is to keep the interface constant and extract it into a Java interface that's statically defined... but it doesn't seem like you can do that (at least, you can't do it and keep any advantages over just using a HashMap).
The result is going to be that it's ten times as hard to write the modules that use this class. Since they don't know the available attributes at design time, they would need to use the reflection API to list and access them, and that would be a pain.
Why are you not just using HashMap again? Or am I misunderstanding something?
 Signature Chris Smith - Lead Software Developer / Technical Trainer MindIQ Corporation
BogusException - 17 Jul 2006 03:29 GMT Chris,
Great thread, and I thank you very much for the discussion. Java is not my strongest language!
> Why are you not just using HashMap again? Or am I misunderstanding > something? I hope the previous post helps, but just in case.. There are 2 questions, and the first one was answered by HashMap. I'll need to create a class that utilizes HashMap, in whole or in part, to allow for attributes/characteristics/data to be added to the object as it traverses the chain of utility classes.
The second problem is the way in which to construct these chains of classes. I'll know the order and name of the classes, but will need to create a larger class that utilizes each of them in the needed order. Another class at that level would use the utility classes in a different order-or not at all.
If ClassLoader is the only way to construct the class objects at runtime (based on a string that holds the name of the needed utility class), then it might work just fine. Unless, of course, there are pitfalls to this approach that make it less desirable than another.
You're not misunderstanding-I'm just misexplaining. :)
TIA!
BogusException
Chris Smith - 17 Jul 2006 03:40 GMT > The second problem is the way in which to construct these chains of > classes. I'll know the order and name of the classes, but will need to [quoted text clipped - 6 lines] > class), then it might work just fine. Unless, of course, there are > pitfalls to this approach that make it less desirable than another. Ah! I was misunderstanding. Please ignore my latest reply.
Yes, you want to use Class.forName for this task, if you've got a list of class names for these utility classes and they are located in the same place as your application code. If they are located somewhere OTHER than your application code, then you'd want to use URLClassLoader instead. In noether case would you want to create a custom classloader as I first implied.
You would typically define an interface that describes how the application interacts with the module, and then have your utility classes implement the methods of that interface. Then once they are loaded, you can cast the resulting reference to the interface type and do as you like.
 Signature Chris Smith - Lead Software Developer / Technical Trainer MindIQ Corporation
BogusException - 17 Jul 2006 03:21 GMT Chris,
> Finally, the most complex possible solution (well, almost) is to use a > custom classloader to build an appropriate class based on your knowledge > of the workflow at runtime. This is probably a horrible idea, but ask > away if you decide you want to do it. I've just started reading about class loaders, and especially:
Class.forName("SomeClass");
Am I reading this to say that as long as I know the fully qualified class name (which I would), and the class is "verifiable" (perhaps needs to be trusted?), I can do what I am looking to do?
Why would you say it is horrible?
TIA!
BOgusException
Chris Smith - 17 Jul 2006 03:36 GMT > Class.forName("SomeClass"); > [quoted text clipped - 3 lines] > > Why would you say it is horrible? It's not that simple. There are two issues here.
1. If you want a class that contains some arbitrary set of attributes assigned at runtime, then you need not only to load that class (which is what Class.forName does) but also to generate it. Generating it is considerably harder than loading it. The Class.forName call relies on the ability to find a SomeClass.class file somewhere, for which "somewhere" by default some directory included in your classpath. Clearly if you don't know about the class at design time, then you can't write and compile such a class. (By contrast, if you did know about it at design time, then you wouldn't use reflection, but would just write and use the class as usual.) This need to genereate the class is where BCEL or similar products come in.
2. Once you've loaded the class, you need to get to those attributes. However, you've only got a reference with type Object. So getting to those attributes means looking them up and accessing their values at runtime, using the reflection API. Reflection is: (a) messy, and more importantly (b) error-prone and fragile, requiring the greatest of care.
 Signature Chris Smith - Lead Software Developer / Technical Trainer MindIQ Corporation
Stefan Ram - 17 Jul 2006 03:58 GMT >This need to genereate the class is where >BCEL or similar products come in. One can use the Java SE 6 JDK to generate classes.
I am showing how to use this to evaluate Java expression at run time on the following web page.
http://www.purl.org/stefan_ram/pub/evaluating-expressions-with-java
BogusException - 17 Jul 2006 20:07 GMT Stefan,
Thanks for posting the URL. Are you saying that what we've talked about so far is easier with the code you provided as an example-as long as I move from v5 to v6?
I must admit, I am not able to follow all the code in that example. In fact, I'm not even that sure what the example set out to do as a use case!
I think what I'm talking about conceptually is something like:
(note: I wrote "class1", etc. with the understanding that they are instances of the classes, not the .class file itself. But with anonymous classes they might not have needed instances..)
// concept only, I'm not suggesting that this is actually possible... x = class3(class2(class1(sSomeString))); // x being the output of classes 1-3 acting (in order) on a string sSomeString.
...where the output of one class is sent to the input of the next. Even if the above worked, I would not know until runtime what the actual classes were for class1-3, as they are loaded from a config file. For even the above to work, each class name, and therefore instance name, woul dbe derived at runtime, and where the above example had 3 iterations/layers, another may have 10, or 2, or ? So whichever way I find to construct the overall class (or in the above case a sort of method), it needs to be flexible. My job is to ensure that each class gets as its input what it expects-but how to construct the "chain" of classes at runtime?
>From what I've read about anonymous classes in Java, they are not the same thing as anonymous arrays/hashes in other languages. I mean, I can't just have as a class name a variable in Java (can I?). Can I do the same thing for nested operations (like above)? In other words, can I go through an XML config file, doing a 'for each', and nest requested classes in the right order until there aren't any more classes needed?
Sorry if this is too difficult for me to explain or for anyone else to understand! I hope it isn't your normal, typical, run-of-the-mill thread!
Thanks again!
TIA :)
BogusException
> >This need to genereate the class is where > >BCEL or similar products come in. [quoted text clipped - 5 lines] > > http://www.purl.org/stefan_ram/pub/evaluating-expressions-with-java Stefan Ram - 17 Jul 2006 21:19 GMT >Thanks for posting the URL. Thanks for looking at the page.
>Are you saying that what we've talked about so far is easier >with the code you provided as an example-as long as I move from >v5 to v6? The Java SE 6 JDK contains support to programmatically compile Java sourcecode to Java class files. However, this is not possible with the Java SE 6 JRE.
>I must admit, I am not able to follow all the code in that example. Most people do not like my formatting style, but you can easily reformat it in Eclipse or other IDEs.
>In fact, I'm not even that sure what the example set out to do >as a use case! To evaluate a Java expression given as a string.
>x = class3(class2(class1(sSomeString))); >// x being the output of classes 1-3 acting (in order) on a string >sSomeString. (...) >I can't just have as a class name a variable in Java (can I?). >Can I do the same thing for nested operations (like above)? Sorry, I do not understand this completely, but possibly someone else in this newsgroup understands it and can answer it.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|