It's not a secret anymore!*
The moose likes Java in General and the fly likes Generating java code programmatically Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Generating java code programmatically" Watch "Generating java code programmatically" New topic
Author

Generating java code programmatically

Mandy Ram
Greenhorn

Joined: May 09, 2012
Posts: 16
Hi,
I want to create java code using java code.

In our project, we map two classes.We copy the values of one object to a different class.For this, we have a mapper class where we set each and every field of the target class.If the target class has 100 fields , our mapper class has 100 lines of code for setting each field in each line.We want to generate this java code dynamically.

We can use BeanUtils.copyProperties for which both the field names in the two classes should be the same.In our case, we have different names for fields we need to copy from one class to another class.

There are other third party frameworks/opensource where the mapping can be done in XML.But, all of them uses reflection API which is not acceptable by our project as it impacts performance.

So,we just want to create plain java code which sets the values from one object to another object.

Once the java code is generated, we want to treat it as normal java code and go through compile process along with the complete project.

It's just that we want to make a GUI where we can drag and drop the fields from one side to other side(from one object to another object) and internally generate the java code for setting those fields.

Can anyone suggest a good method to generate java code programmatically?Is there any API to create java code programmatically?

I have googled and found couple of APIs (Eclipse JDT,JAnnocessor,Sun CodeModel and others)for generating Java code but not sure which is better.Please suggest.


Thanks in advance.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 39547
    
  27
But, all of them uses reflection API which is not acceptable by our project as it impacts performance.

Does this describe an actual problem that you experienced, or is it based just on rumors you heard/read? While it's true that using reflection is slower than performing the same operation directly in Java code, it's still very fast. You shouldn't make decisions based on that unless you have done extensive timings with all the available frameworks and determined that none meet your requirements.

Plus, using someone else's debugged and optimized code is a heck of a lot faster than writing and debugging your own.


Ping & DNS - updated with new look and Ping home screen widget
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 13872
    
  10

There are libraries which do things similar to what you want. Have a look at Dozer and Orika. I've never used either, so I don't know if they exactly match your requirements.


Java Beginners FAQ - JavaRanch SCJP FAQ - The Java Tutorial - Java SE 7 API documentation
Scala Notes - My blog about Scala
Mandy Ram
Greenhorn

Joined: May 09, 2012
Posts: 16
Ulf Dittmer wrote:
But, all of them uses reflection API which is not acceptable by our project as it impacts performance.

Does this describe an actual problem that you experienced, or is it based just on rumors you heard/read? While it's true that using reflection is slower than performing the same operation directly in Java code, it's still very fast. You shouldn't make decisions based on that unless you have done extensive timings with all the available frameworks and determined that none meet your requirements.

Plus, using someone else's debugged and optimized code is a heck of a lot faster than writing and debugging your own.


Thanks for your reply.Actually, I didn't face any problem but the project in which am working presently implemented some business logic using reflection API and faced performance degradation and so they are not giving a go ahead for reflection API for this implementation.

Mandy Ram
Greenhorn

Joined: May 09, 2012
Posts: 16
Jesper de Jong wrote:There are libraries which do things similar to what you want. Have a look at Dozer and Orika. I've never used either, so I don't know if they exactly match your requirements.


Thanks for your reply. Will look in to both of them.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 39547
    
  27
Mandy Ram wrote:Thanks for your reply.Actually, I didn't face any problem but the project in which am working presently implemented some business logic using reflection API and faced performance degradation and so they are not giving a go ahead for reflection API for this implementation.

That doesn't make sense. Just because project A faces certain issues doesn't mean project B will face the same issues. You need to challenge such blanket assumptions. Using reflection for this purpose is done by lots of libraries and millions of users round the world without problems. It sounds a bit like one of these assumptions about Java performance that date from 1996, and have long since been addressed, yet are still being repeated like mantras by some folks to this day.
James Boswell
Bartender

Joined: Nov 09, 2011
Posts: 973
    
    5

Mandy

I have used Dozer (as suggested by Jesper) extensively and found it to be an extremely useful library. Saves you having to write loads of setter and getter mapping code. The mappings in Dozer are defined using XML configuration files although recent versions have started to use annotations. I would recommend having a good suite of unit tests to go along with your mappings.

Be aware that Dozer does use reflection under the hood though.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7052
    
  16

Mandy Ram wrote:So,we just want to create plain java code which sets the values from one object to another object.

Ooof. This sounds:
1. Horribly tortured.
2. A "lazyman" solution.
3. A tester's nightmare.
4. Like somebody is already dictating how you're going to do this before fully analysing what the alternatives are.

Just off the top of my head I suspect that some variant of the AbstractFactory or Builder patterns might be applicable. Alternatively, have each object hold a Map of "fields" accessible by name (I suspect that this may be something like what BeanUtils does, but I really have no idea).

Finally, you need to ask yourself whether Java is actually the right language for doing this. It sounds to me like the sort of thing I might do in a scripting language (or Smalltalk, for those that remember ); but personally, I wouldn't touch it with a bargepole in Java.

Winston

Isn't it funny how there's always time and money enough to do it WRONG?
Artlicles by Winston can be found here
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Winston Gutkowski wrote:
Finally, you need to ask yourself whether Java is actually the right language for doing this. It sounds to me like the sort of thing I might do in a scripting language (or Smalltalk, for those that remember ); but personally, I wouldn't touch it with a bargepole in Java.


What about a "scriptable Java," such as Groovy or Beanshell?
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Ulf Dittmer wrote:
Mandy Ram wrote:the project in which am working presently implemented some business logic using reflection API and faced performance degradation

That doesn't make sense. Just because project A faces certain issues doesn't mean project B will face the same issues. You need to challenge such blanket assumptions. Using reflection for this purpose is done by lots of libraries and millions of users round the world without problems. It sounds a bit like one of these assumptions about Java performance that date from 1996, and have long since been addressed, yet are still being repeated like mantras by some folks to this day.


Indeed.

It's trivial to create a test to actually measure the performance.

To wit:

I whipped up this little test to copy fields from objects of one class to differently named fields of objects of a different class. To make the test more pessimistic, I assumed that each time we had to do all the introspection work for both classes. That is, we naively pretend we don't know that it will be the same getters and setters every time. There's no caching of the introspection results. The only "optimization" I did was to build maps (rebuilt for each pair of objects) mapping the property name to the get/set method, so as to avoid O(n^2) performance on linear searches through the ProperyDescriptor arrays.

It took 793 ms to copy 30,000 fields (30 fields each for 1,000 pairs of from/to objects). That's 26 microseconds per field, or nearly 38,000 fields per second. On a cheap laptop. With more work in the tight loop than an intelligent approach would use.

Maybe the equivalent performance on your production host will be enough, maybe it won't be. But it shouldn't take you more than an hour or two to find out, and then you can make your decision base on proper criteria.

Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Just for giggles, I took the introspection out of the loop, to simulate caching its results, which you would almost certainly do in a production environment.

The time dropped from 793 ms to 136 ms. 4.5 microseconds per field copy. 220,000 field copies / sec. On a cheap laptop.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7052
    
  16

Jeff Verdegan wrote:What about a "scriptable Java," such as Groovy or Beanshell?

Or indeed, JPython or JRuby (although I'm not sure that they qualify, not being an expert in either).

@Mandy: Your basic problem is that you are trying to turn a Java class into a first-class object and, since the language doesn't support this, whatever solution you come up with will be a work-around. Personally, I wouldn't like to base an entire project on a kludge.

Winston
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Winston Gutkowski wrote:
@Mandy: Your basic problem is that you are trying to turn a Java class into a first-class object and, since the language doesn't support this, whatever solution you come up with will be a work-around. Personally, I wouldn't like to base an entire project on a kludge.


Is she "basing the entire project" on it though? That is, it may be that this field copying stuff is an important but small part of the overall application. If so, then reflection or code generation may actually be a small and worthwhile kludge, in the scope of the overall project. And I'm not convinced that reflection is necessarily a kludge here.

Having said that, though, development and maintenance may go much more smoothly if this piece can be done with a scripting language. I would expect, though, that if it's scripting that ends up manipulating Java objects in a JVM (because it needs to interact with the rest of the app), it will probably be implemented as reflection under the hood, and so if performance does turn out to be a legitimate problem for reflection, it probably will be for scripting too.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7052
    
  16

Jeff Verdegan wrote:Is she "basing the entire project" on it though?

Maybe not, but from the sound of it she's building on previous (or similar) versions that have "done things this way", which worries me.

As far as I can see, this is the equivalent of a javac "pre-processor", which the designers of Java sought fit to ignore. All other things being equal, I tend to trust those buggers, because they were a pretty smart lot.

On the other hand, a script-based pre-processor module? Hey, it takes all sorts...

[Edit] I also wonder if something equivalent couldn't be done with a dependency injection system like Guice.

Winston
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2052
    
  22

Like Jeff proved, introspection of classes is much heavier than calling the getter and setter methods. Calling the getter and setter methods via reflection is not much heavier than making the calls themselves. A very common pitfall while using reflection is to not cache the results of your introspection, which is why reflection tends to get a bad rap. Used correctly, reflection shouldn't add too much of overhead

A lot of the mapper libraries (and I believe Dozer does it too) have 2 phases:- A Mapper phase and a conversion phase. The Mapper phase occurs only once, and they reccomend you to keep singletons of mapper objects created in Mapper phase. Then converter phase occurs whenever you convert objects. You use the mapper to convert your objects. Internally, the mapper does the introspection upon initialization, and holds on to the results of the introspection. When you ask the mapper to convert, it just calls the getter/setter methods. This usually results in performance that is very close to calling getter/setter methods yourself

Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7052
    
  16

Jayesh A Lalwani wrote:A lot of the mapper libraries (and I believe Dozer does it too) have 2 phases...

I must be getting very old. I thought design was about using the right tool for the job; and surely that includes languages as well?

I can't imagine that a library, even one designed expressly for making classes first-class objects is likely to do it any better than a language (or script) which has it expressly built in; and I imagine it's likely to run into all the usual problems associated with strong typing and compilation (ie, copious casting of resulting objects).

However, Hibernate seems to have managed to put a lot of this stuff "under the hood", so I'm ready to be convinced otherwise. I'll be having a look at Dozer over the coming days.

Winston
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Winston Gutkowski wrote:
Jayesh A Lalwani wrote:A lot of the mapper libraries (and I believe Dozer does it too) have 2 phases...

I must be getting very old. I thought design was about using the right tool for the job; and surely that includes languages as well?

I can't imagine that a library, even one designed expressly for making classes first-class objects is likely to do it any better than a language (or script) which has it expressly built in;


Part of it goes back to what I said previously. Maybe Java is the right tool for 95% of this job, and it's close enough for the other 5%, to where it's not worth using a different language for that 5% and then having to split that piece off and coordinate the interaction of the Java piece with the Language X piece.

There's always going to be some compromise somewhere. But then, I suspect you might already know that.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7052
    
  16

Jeff Verdegan wrote:But then, I suspect you might already know that.

Of course, but I do like to stir the pot - especially when I think that an approach may be being taken simply because "it's worked before" - and, to be honest, that's the thing that worries me most about what I've heard so far.

And if it is indeed a "pre-processor", there may be an argument for separating it completely and using a different technology.

@Mandy: All this esoteric stuff aside, do you know if anybody's actually had another look at the design of this requirement? ie, whether it really has to be done this way at all?

Winston
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2052
    
  22

I don;t know.. I think I will have a hard time convincing my boss that we have to port over to a whole new language because I want to do bean to bean conversion

Just sayin...
James Boswell
Bartender

Joined: Nov 09, 2011
Posts: 973
    
    5

It sounds like Mandy simply wants to avoid writing potentially a load of boilerplate code and thinks generating it instead is the way to go. Personally, Dozer will do the job, as long as there is allowance to learn and get used to a new library.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 39547
    
  27
Bottom line: unless the circumstances are very special (and there's nothing to indicate they are so far), tools that use reflection are most likely just fine performance-wise.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Generating java code programmatically
 
Similar Threads
java xml bindings & transfer objects
instantiate objects
K&B scjp5 Exercise 9.2 - Synchronizing a block of Code (Chapter 9: Thread)
How to generate charts using cewolf
DTO/VO or a Universal Map