June 8, 2007
Today I realized what we (or may be just I) live in very strange world. Let me describe why.
I work now on problem of making GORM domain classes accessible in GWT client-side code. It is an interesting task by itself and I plan to dedicate several separated posts to it but in general it is very simple. I want to define my server data objects in Groovy and be able to request them in from client-side code without coding too much.
The solution is almost trivial. GWT provides great idea of generators which can create Java code to be integrated in to compilation of client-side JavaScript, so all what I need is to implement generator, which read groovy classes and generate all additional Java code I need. It is not too compilcated especially with Groovy in your hands.
What I realized debugging my code is how many different compilers, generators and even instrumenters involved in run of my one single test.
- Javac. I use it to compile Java part of my generator and the test to be run by JUnit.
- Groovyc. Most interesting part of my generator is written on Groovy
- GWT compiler from Java to JavaScript. It calls my generator and compile my test and generated Java code. If you curious, it contains built-in parser from Eclipse compiler
- BTW, compilation of unit tests in GWT involves generation of client-side part of the test. It’s a long story, which I will probably need to blog separately later. For now we just notice one more generation step.
- My generator use Groovy compiler to parse Groovy sources of domain classes. Main task for the generator is to create client-side twins for domain classes and make them serializable.
- Of course, serialization may not happen for free. Fortunately GWT provide default generator, which takes care for generation such code for java source, generated by me.
- Again, just for record we should notice that my generator not only written on Groovy but also depends on Groovy runtime, which does some code instrumentation in magical GroovyClassLoader.
- There is one more thing, which I am afraid to speak about. GORM uses Hibernate and Spring. How many code generation and instrumentation used inside? God knows.
- I know only that even GORM iteself uses some to access Hibernate and Spring.
That’t it. But something is wrong in this world, isn’t it?
2 Comments |
Generative programming, Grails, Groovy, Opinion |
Permalink
Posted by groovyland
June 7, 2007
There’s been a lot of people asking for a Java loop syntax in groovy. A lot if not almost all usages however are cleaner without it, once you know some idiomatic Groovy.
Marc Palmer’s post blog post demonstrates it almost obviously.
No Comments » |
Uncategorized |
Permalink
Posted by groovyland
June 6, 2007
In my previous post I promised to describe how to compile Groovy and Java together without writing complicated ant scripts or limiting yourself in design decisions.
Let us analyze the problem and probably it will lead us to a solution:
- To compile Java code, which refers some Groovy code, we have to compile Groovy first because the only way for javac to know about Groovy is .class file
- We can’t compile Groovy code if it has to know about Java one because again the only way for groovyc to know about Java code is .class file form.
- But do we really need as much? Obviously, not. We don’t really need compiled Groovy classes during Java compilation. All we need to know are “exported interfaces” of the classes. What are their names, methods, fields, implemented interfaces, superclass etc. We don’t care about real implementation at all. Let me repeat it is once more. We don’t need it at all.
- So if we are able to supply javac with .class files with the same “exported interfaces” as our Groovy classes we are done. After that we are able to compile Java code and provide compiled code to groovyc. And our circular dependencies will be resolved.
- It is cool, isn’t it? All we need to do is to write simple compiler which will take Groovy code and create .class file with the same “exported interface” as our Groovy code but ignoring all implementation logic, possible errors etc.
- But how does it help us with “ant script problem”. Unfortunately, it doesn’t because we need to call this special compiler.
- Wait a minute. Why do we need additional compiler? We can build it in groovyc itself. It will be one task to call for joint compilation of Groovy and Java code, which will do three passes internally. First pass will generate dummy .class files, usually such things called stubs. The second one will call regular Java compiler, for example javac or eclipse compiler if we like. And the final step will do usual Groovy compilation. And it is exactly what we need, isn’t it? Yes, it is exactly what we were looking for.
- So the only problem we have is to patch groovyc. We know how to parse and even compile Groovy sources. We know how to call external compiler. We have great ASM library, which will help us to generate stubs. We just need to put it all together. Not too complicated. Right?
- OK, there is one more problem, which still worry me. I know that ASM is great library but I have no too much experience with it and it may take long time to code and especially debug this code. Sounds like a problem, right? Really not at all! We don’t need compiled classes. What we need is to provide javac with information about “exported interfaces” of our Groovy code. It can be .class files or … Java source. Let us just generate Java sources with exactly the same “exported interfaces” as our Groovy code. It is really easy task if you have parser for Groovy, which we obviously have, and what can be easier than such generator? “Hell, World!” probably.
- We have last thing to improve. Currently we plan to parse Groovy code twice - once for stubs generation and once more during Groovy compilation. It is not dramatically bad but unpleasant. Fortunately, it is easy to resolve. What we need is to incorporate our patch in the middle of Groovy compilation process. Parse Groovy, generate stubs, compile java and stubs and continue Groovy compilation. What is even more fortunately is that Groovy compiler is modular enough to allow it.
What’s it. We found solution for all our problems and our quest completed. There is interesting story about different technical details and difficulties, which I met implementing this approach, but I will describe it in the later posts.
And wait a second. The patch gonna be incorporated in to Groovy trunk in nearest days.
No Comments » |
Groovy, How-To |
Permalink
Posted by groovyland
June 5, 2007
The first thing I’ve learned about Groovy was that you have to compile it separately from Java. OK, it is understandable because the languages are different.
But the next news was even worse. There is no way to compile it correctly if there are dependencies between Groovy and Java code. Again, of course we are software engineers, everything is possible(c) and there is a such possibility but…
Let me give you a sample. Imagine we have
- Java interface JInterface
- Groovy class GClass implementing JInterface
- Java class JClass, which has to create instance of GClass (probably not thinking too much is it Groovy or Java class) and use it as instance of JInterface
I believe everybody will agree that such design may be very logical in some situations. But how can we compile this code? Well, we do it in three steps of ant script
- javac for JInterface
- groovyc for GClass
- javac for JClass
And here we are. Our problem resolved. May be the solution is not so elegant (carefully written ant script instead of IDE compilation) but it works. And it is what Groovy coders do every day.
But does the solution above really work? No, unfortunately it doesn’t!
Imagine that by some reasons JInterface has to know about GClass. We can argue long hours is it good design or bad one, so let just think it has to. Now we have circular dependencies between Groovy and Java code. To compile Java we need to compile Groovy first but to compile Groovy we need to compile Groovy. Ooops! We have dead lock.
Obviously, it is not new problem. Have a look on issue http://jira.codehaus.org/browse/GROOVY-1735 The problem is nobody knows how to solve it.
Again, we can refactor our design. Probably introduce some additional class. May be add additional step to our carefully written ant script and finally being able to compile our simple code. But does it make us more productive? I am not sure.
Fortunately I have some good news. There is a solution for joint compilation of Groovy and Java. Some nice trick was invented by guys from JetBrains And I can say even more - the’ve submitted patch, which probably will be accepted before Groovy 1.1 Beta 2 is out.
But I will describe this story tomorrow. Stay tuned 
No Comments » |
Groovy, How-To, Opinion |
Permalink
Posted by groovyland
June 5, 2007
Luc Dewavrin recently discovered Spring’s ability to declare beans that are script-based. He describes why this is great and helpful to to speed-up development. Sample declarations and scripts are also provided.
The article ends with interesting opinion “…, I like both Groovy and JRuby but now tend to prefer Groovy because it leverages my knowledge of Java API. With Ruby i spend too much time finding the reference web site how to achieve things that i do almost naturally in Java. OTH, Ruby has its core API use closures. Closures are tightly integrated and tend to favor loose coupling.”
Read full story…
No Comments » |
Groovy, How-To, Opinion |
Permalink
Posted by groovyland