I did a GWT project in the past (GWT version 1.4) and it was extremely painful.
Interface is build with code (which it is really bad), requires a lot of slow compiling and waiting, unit testing was awful. Not to mention that integrating with Hibernate was the most annoying thing.
But it looks to me that GWT is really hot among Java developers and I'm reconsidering it.
Have you tried GWT 2.x? is it better now? I'm particularly interested in the three previous points (slow compiling, UI building and unit testing).
Let's address your three main complaints one-by-one.
Slow compilation
This is really a lot better now in a number of ways.
Compilation has become faster.
The GWT compiler can compile several permutations in parallel.
The (god awful) "hosted mode" browser has been replaced with a "development mode" browser plugin so that you can test in your favourite mainstream browser without compilation.
UI building
Yes. UiBinder.
Write HTML "templates" that include elements that act as placeholders for widgets. Elements representing panels (widgets that can contain widgets) can contain elements representing other widgets.
Yes, there will still be some aspect of composing widgets in Java, but this is now greatly reduced.
Unit testing
How was it awful before? Your logic code can still be run through JUnit. Recently, there has been a much heavier push toward MVP design in GWT, so presumably much more of your code can be tested with plain old JUnit.
GWT also has a manner of unit testing where a non-interactive browser is run. In my experience this can usually be safely avoided when using plenty of JUnit tests both for client (presenter) and server code.
Related
In the open source project JChemPaint, for example, the GUI is tested (using the FEST framework) by collecting about a dozen individual tests each into a few Java files. The applet is started only once per file, and several independent tests are performed in a chain.
I would like to know if this is good practice. Of course, starting up each time would cost time. I can see however problems with side effects of previous actions and possible exceptions, but I'm no expert. So, is it good practice to put several tests into one applet start?
(I'm looking also for a collection of best practices for GUI testing but can't pose such a question, hints are welcome nevertheless.)
I'm troubled by the awkward division between these two top-level containers:
org.openscience.jchempaint.application.JChemPaint
org.openscience.jchempaint.applet.JChemPaintAbstractApplet.
After cursory reading, I am reluctant to be critical; but re-factoring the contents might limit the amount of duplicate testing required. In this very simplified example, common initialization is confined to the initContainer() method. By comparison, JChemPaint is considerably more complex and offers a number of applet parameters, the correct transfer of which should be tested.
Such re-factoring may be on-going. The appletests appear to date from an earlier period of development, while the newer jchempaint.src.test artifacts appear to reflect a more recent, annotation-based testing architecture.
I was wondering if someone who was experienced in both technologies could give an objective comparison between the two, assuming you were building a complex web application that would be both very rich in on the server and in the browser.
One problem with the older paradigm, for me, is testability of the Spring MVC layer. I find that there's a lot of bugs that can creep into your application due to untestable annotations. This model also slows development cycles because you have to restart the server to make changes to the annotations/controller code... which is something I personally find very annoying.
I also don't want to deal with the complexity of javascript. Working with and testing an application all in Java sounds appealing to me. I don't really want to master another language, and learn all of its quirks, weird design decisions, idiosyncracies and the full history of browser incompatibilities.
So for a complex application, would GWT offer a superior approach? Are there any serious limitations to this approach over Spring MVC, which would probably be more flexible although harder to work with? Are there any gotchas and road blocks that are common for building complex applications?
I would really appreciate a comparison between the two. Please keep in mind that I have no experience with GWT, but about 10+ years experience with Spring. Thank you!
The truth is that also GWT has a learning curve and also at least at the time I looked at it, two years ago, you're not doing much with the basic controls, you need external libraries and that means more learning.
After trying to learn GWT without much success, I opted for a webservice plus either jQuery or ExtJS, which also gives a very clean separation of the roles. I sat down and learnt JavaScript, it wasn't easy but it was immensely more fun than using GWT.
As for browser compatibility, once you use a modern library, you'll have very few of them. My code works in all browsers without too many problems, including IE 6. Also when I am too busy, I write the services only and outsource the JavaScript interface part, which allows increased productivity.
Anyway, this is fairly subjective, another person fluent with GWT, can have an opposite point of view of mine. I will anyway reject the following reasons:
ease of debugging. Not true anymore: it's very easy to debug JavaScript with FireBug, plus there won't be any business logic in JavaScript, only services call and display.
browser compatibility. There are very few quirks to remember, the most common one is that IE doesn't accept trailing commas in lists, which is anyway not in the standard, but Firefox tolerates them. Any modern JavaScript library will take care of compatibility for you.
Speed. To start with I will state that JavaScript is very fast for any reasonable computation within the browser. What is slower is DOM manipulation and of course anything involving the network, like AJAX calls. Your page will perform just right if you don't do design mistakes, like stuffing too many things or other problems that can arise when adding many elements directly to the DOM, instead of building your structure and then attaching it all at once.
As far as I can think now, the only valid reason is, I already know Java, I don't want to study another language.
As for your comment on Spring MVC. I am using Spring MVC and I don't feel the pain of restarting the server. The whole point of Spring is that everything should be easy to work with outside the container! In the Spring controllers I've very minimal code that just call the underlying services. What I need to unit test well are the services.
The controllers have very few code to test, I could just call them and test them within JUnit, but, at least for now, my approach is having a simple external test done through a web page with jQuery calls that check their response (it's not unit test, it's an integration test, but I feel there is a very little value to unit test a controller, if it's written properly).
I am using GWT for more than a year now in a complex project (200 KLOC for the whole project), and I recommend you to give GWT a try.
In my opinion GWT is quite easy to learn, there are really good tutorials about how one should use this technology.
The advantage of using GWT is that one can build nice, fast, maintainable web apps, without knowing very little about browsers or javascript. You can also debug your client side code with a Java debugger and in complex apps this is huge.
Although GWT offers the possibility to properly unit test the client side code, this requires a good understanding of GWT's MVP paradigm and careful planning. If you mess up your code (which is not that hard, because GWT gives you total freedom) then you are going to end up losing this feature, but this is your fault, not GWT's.
It took me a couple of months to learn Spring well enough to create fairly basice MVC apps. It took me about a month to master GWT. (It could be that it was easier because I had already worked with Android for three years and it works similar. It even has the exact same unobvious solutions to some of its problems.) So for me, GWT was definitely much easier to learn than Spring.
I do Java web development work using Spring MVC and basically I'm forced to do an Agile type of development where I have to make a lot of small changes and I sometimes end up wasting a lot of time having to compile each time I make a change ( I work for a start-up company and I am not given enough time to make unit tests, etc, this isn't ideal and I don't necessarily plan to stay with the company long-term but am just looking for ways to be more adaptable for the moment).
The app I'm working on needs to be fast and it does a lot of high volume data processing (its sort of a search engine but not a web search engine) so it has to be regular compiled Java for the production app but I'm wondering if I used Groovy with Grails, or something similar, for development if I could just write it as regular Java but then test code in real-time without having to recompile. I'm wondering how much effort would be involved in doing this as far as making it work then as compiled Java. Sorry if this is a newbie question I just am not sure where to look for info on this as most things about Grails seem more geared towards emulating scripting languages not what I am trying to use it for.
Agility is a state of mind, it doesn't have anything to do with a programming language or framework. I never have enough time NOT to do unit tests.
If you are coding in Java, code in Java, not in Groovy. Groovy is an (almost) superset of Java, so you could theoretically write your classes in Groovy and then compile them as Java, but this approach has a number of problems:
1) It's very easy to slip something in your code which isn't correct Java, closures are just SO useful :-)
2) Grails isn't easily translatable to Spring MVC, so you'd have to rewrite that bit as well.
So, I personally would not use Groovy/Grails.
When you say compile, do you really mean build the war and redeploy? Most IDEs (Eclipse, Intellij, etc) recompile a class as you save the file, so there is no delay. Assuming you're using such an IDE, you can run your (Tomcat) server from within Eclipse, and stuff gets automatically redeployed, and if necessary Tomcat restarts automatically.
If this still isn't fast enough, I recommend JRebel, which was so good that i forked out real money for a license. Using JRebel means that you (usually) don't even have to redeploy. You change a Java file in the IDE, and the change happens in your server without having to redeploy. I would highly recommend it.
One other thing I would do is to write unit tests for your code. You don't need to check them in, but they are a tool which will help your productivity.
What I would do here would be to embed groovy scripts within the java code as described here:
http://groovy.codehaus.org/Embedding+Groovy
In this way you can change your groovy code without the need to recompile. We've used this technique in our last legacy app that took 10-15 mins to recompile and install.
Groovy runs within the JVM and is dynamically compiled to bytecode, so there's no need to worry about the "production-ness" of it.
I've got a problem and I'm asking you for help
I've started working on web application, that has no tests, is based on spring 2.5 and hibernate 3.2, is not very well modularized, with classes having up to 5k lines, as view technology there is JSP used all over the place with quite a lot things duplicated (like many similar search forms with very few differencies but with not many shared parts).
Aplication works well, however, everything is running just fine, but when there is need to add or to change some functionality, it is realy slow and not very convenient.
Is there any possibility to employ TDD at this point? Or what would you recomend as I dont't think I can develop it forever the way it is now, it is just getting messier all the time.
Thanky you for answers.
I would start by picking up a copy of Michael Feathers' book Working Effectively with Legacy Code - this is pure gold.
Once you learn techniques for refactoring and breaking apart your application at it's logical seams, you can work on integrating TDD in newer modules/sprout classes and methods, etc.
Case in point, we recently switched to a TDD approach for a ten year old application written in almost every version of our framework, and while we're still struggling with some pieces, we've made sure that all of our new work is abstracted out, and all of the new code is under test.
So absolutely doable - just a bit more challenging, and the book above can be a tremendous help in getting started.
First, welcome to the club of poor good programmers that have to fix crimes done by their worse colleagues. :(
I had such experience. In this case one of the recommended practices is developing tests for new features. You cannot stop now and develop tests for whole application. What you can do is every time you have to write new feature develop tests for this feature also. If this feature requires changes in some sensitive places start tests for these places.
Refactoring is a big problem. Ideally if you want to separate 5k lines class to 10 normal size classes you should first develop test case(s) for the big class, then perform refatoring and then run tests again to validate that you have not break anything. It is very hard in practice because when you change the design you change the interface and therefore you cannot run exactly the same tests. So, each time you should make the hard decision what is the best way and what are the minimal test case that covers your ass.
For example sometimes I performed 5 phase refatoring:
1. developed tests for bad big class
2. developed new well designed code and changed the old class to be the facade for my new code.
3. ran the test case developed in #1 to validate that everything works
4. developed new tests that verify that each new (small) sub module works well
5. refactred code, i.e. removed all references to the big old class (that became lightweight facade)
5. removed the old class and its tests.
But this is the worse case scenario. I had to use it when code that I am changing is extremely sensitive.
Shortly, good luck in your hard job. Prepare to work overnight and then receive 20 bug reports from QA and angry email from your boss. :( Be strong. You are on the right way!
If you feel like you can't make any changes for fear of breaking stuff, then you have answered your own question: you need to do something.
The first rule of holes is: If you are stuck in a hole, stop digging.
You need to institute a policy such that if code is committed without a test, that is the exception and not the rule. Use continuous integration and force people to keep the build passing.
I recommend starting by capturing the core functionality of the app in tests, both unit and integration. These tests should be a baseline that shows the necessary functionality is working.
You mentioned there is a lot of code duplication. Thats the next place to go. Put a test around an area with duplicate code. You will be testing 2 or more items here, since there is duplication. Then do a refactor and see if the tests still pass.
Once you knock one domino down, the rest will follow.
Yes there is definitely a place for TDD, but it is only a part of the solution.
You need to refactor this application before you can make any changes. Refactoring requires test coverage to be in place. Take small portions of obviously substandard code and write characterisation tests for them. This means you test all the variations possible through that code. You will probably find bugs doing this. Raise the bugs via your QA system and keep the buggy behaviour for now (lock the bugs in with your characterisation tests as other parts of the system might, for now, be relying on the buggy behaviour).
If you have very long and complex methods, you may call upon your IDE to extract small portions to separate methods where appropriate. Then write characterisation tests for those methods. Attack big methods in this way, bit by bit, until they are well-partitioned. Finally, once you have tests in place, you can refactor.
integration tests can be useful in this circumstance to highlight happy-day scenarios or a few major error scenarios. But usually in this circumstance the application is far too complex to write a complete integration test suite. This means you might never be protected 100% against side-effects using integration tests alone. That is why I prefer 'extract method' and characterise.
Now that your application is protected from side-effects, you may add new features using TDD.
My approach would be to start adding tests piece by piece. If there is a section you know you're going to have to update in the near future, start getting some good coverage on that section. Then when you need to update/refactor, you have your regression tests. From the sounds of it, it will be a major undertaking to establish a comprehensive test suite, but it will most likely pay off in the end. I would also suggest using one of the various code coverage tools available to see how much your tests are actually covering.
Cheers!
You probably can't do test driven development at this point, except if you happen to add functionality that is easy to isolate from the rest of the system (which is unlikely).
However, you can (and should) certainly add automated tests of your core functionality. Those are at first not going to be real unit tests in the sense of testing small units of code in isolation, but IMO the importance of those is often overstated. Integration tests may not run as fast or help you pinpoint the cause of bugs as quickly, but they still help tremendously in protecting you against side effects of changes. And that's something you really need when you refactor the code to make future changes easier and real unit tests possible.
In general, go for the low hanging but juicy fruit first: write tests for parts of the code that can be tested easily, or break easily, or cause the most problems when they break (and where tests are thus most valuable), or ideally all of these together. This gives you real value quickly and helps convince reluctant developers (or managers) that this is a path worth pursuing.
A continuous build server is a must. A test suite that people have to remember to run manually to get its benefit means that you're wasting most of its benefit.
I don't have any knowledge of Java platform and I wonder which tools (and methodologies) could be used to help developing maintainable code written in Java.
I know one can use:
Agile methodology in any environment
jUnit/jMock for unit testing code (similar to NUnit/Moq in .net world)
Checkstyle for coding standards - is this similar to StyleCop or FxCop or both?
I suppose you can also write layered applications in Java (like assemblies for different tiers in .net)
Are there any automated testing OSS/Licensed tools that are worth mentioning
Are there any code generators that are very popular in Java world
Are there also any other popular tools/methods that a Java developer/team can use that I don't have access to in .net world? Would you suggest other tools and approaches in Java world?
In java there are a lot of frameworks. For example, you don't have to use JUnit, you could use TestNG with basically just as much tool support. There are several mocking frameworks as well.
In terms of coding standards, IDEs come with that built in, as well as there being several others available (I'm most familiar with the IDE ones, so I don't know names off hand).
You have Eclipse as an IDE if you want free, as well as NetBeans and for money there is IntelliJ IDEA among others. Then there are some IDEs from big vendors intended to support their specific application servers.
In terms of building "assemblies" (jars, wars and ears in the java world), there are some built in tools in IDEs for one-man projects, and there is Ant or Maven for a full fledged build tool.
There are many options in automated testing tools. If you mean continuous integration, there is CruiseControl that is free, and TeamCity which has no cost for low usage.
In terms of code generators, in general the Java world is kind of trying to move away from them in favor of annotations, but the name that comes to mind is xdoclet. In GUI building there are a bunch of code generators strictly for building the GUI of course.
That really barely scratches the surface. For example, application servers (JBoss, Oracle (they now own two with the Sun purchase) and IBM among others) are a big decision point in many Java projects (it depends what kind of project).
None of the categories discussed are intended to be exhaustive, just enough to give you a jumping point of what to look into. There are many more in each category.
The great thing about Java is that there are so many choices. The bad thing about Java is that there are so many choices ...
Responding to #2: Code coverage tools like EMMA are often used to evaluate the extent of current tests.
Responding to #5: Findbugs and PMD are extremely popular static analysis tools.
You can use Hudson together with ant or maven as an continuous integration server. Testing your code at specific times and after each checkin. You can combinte Hudson with JUnit, Emma, FindBugs, Pmd and checkstyle to measure the quality of the code in your repository. If you are doing this I recommend installing the continuous integration game giving your developer a high score for fixing tests and warnigns, and negative points for breaking them.
The best tool for Java development is great Java programmers.
If you manage to hire a few that are really good, the rest will take care of itself :)
I'm not convinced that any one set of tools/methodologies/processes will guarantee you get maintaniable code at the end of it. So much of this comes down to the programmers who develop the project. Are they craftsmen/women committed to producing excellent code or just code-cutters aiming to get the job done. Looking at it another way, it's possible to have great processes in place and still produce poor code. And great programmers can produce maintainable code despite poor processess/tools or the lack of them.
That said, I'd still insist on the basics: source code control, branching for each change with regular check-ins to the main branch, automated build and test, lots of test code, basic static analysis, bug tracking and so on. That's on the tool side. On the coding side, regular design and code reviews, n-tiered architecture, loose coupling, etc. Most of this is language independent. So what's been working for you in C# should translate to Java.
For Java, I've found JUnit very good for test code and Checkstyle pretty good for maintaining a coding style.