Friday, December 31, 2010

GWT Temp Directory

The other day, my all-star colleague was sifting through his hard drive and found that his temp directory had become horribly bloated.




Looking through the folder, he found a ton of GWT-generated files. It turns out that in both debug and compile, GWT is creating temporary files and using the default system temp directory to store them. He brought this to my attention.

me: Doesn't seem unreasonable.

colleague: But it's not cleaning them up.

me: Hmm..

colleague: ...and it's like >1gb of files!!


Ok! That could lead to some performance issues. Worth trying see if we can fix it.

A little bit of hunting, and he found Development Mode Options and GWT Compiler Options sections on the Compile & Debug page of the official GWT online documentation.

In both sections, it lists:

-workDir         The compiler's working directory for internal use (must be writeable; defaults to a system temp dir)


Turns out that's the one that if left blank causes our default temp directory[1] to get full of crap.

Solution:

In our Eclipse Debug Configuration and in our Ant build script, we specify a new directory within the project's /build directory that we'll reserve exclusively for GWT's temp files.

Since we already clean the /build directory with every launch, we're sure to clean out these GWT temp files as well --Problem Solved!

Not Quite:

Compiling:
Here, when we specify the -workDir argument, we do see the new gwt-specific temp directory get created and populated with generated files.

However, if we open our system temp directory and monitor it during the compile, we see that GWT is actually still using the system temp dir for some other temporary files. Drat!

When the compiler finishes, it does clean itself up nicely. Phew!

If, however, you stop things mid-compile[2], those temp files will be orphaned. :-( Good to know.

Debug:
Adding a -workDir specification in our Debug Mode Configuration didn't seem to do anything at all. The specified directory remained empty before, during, and after the debug run. Meanwhile, our temp directory continued to get filled with temp files, which are not removed on exit from debug mode:



Conclusion:

In the end, it seems unclear whether or not it's worth the effort of setting the -workDir option in your debug and compile configurations.

As far as we could tell, GWT uses the system temp directory no matter what.

Depending on whether you are running principally in debug or full compile/deploy mode, you may see fewer files piling up there, but either way...

After a couple months of concentrated GWT work, you probably want to go in and do a little manual housekeeping on your system's temp directory!




[1] In Windows 7, the directory seems to be c:\Users\USER_NAME\AppData\Local\Temp

[2] With a decent-sized project, you'll eventually get to where the compile phase is upwards of 3 minutes, in which case you're almost sure to change your mind mid-compile from time to time.

Tuesday, April 27, 2010

We are Looking for Java/J2EE Developers and a Technology Team Leader

If you're a talented programmer and/or team leader living in the NYC metro area looking to work for a cool up-and-coming company where the sky is the limit, we want to hear from you!

Required Experience:

  • at least 6 years Java development experience in a team environment
  • team leadership experience
  • experience with J2EE and either Servlets or JSPs, the more the better
  • developed at least one multi-tier application that connects to a relational DB using JDBC
  • experience using an IDE (ideally Eclipse, but IntelliJ or other is fine)
  • at least basic comfort working with HTML/CSS
  • comfortable working as a user on both Windows XP and at least one linux distribution or unix OS
  • 4-year computer science bachelors degree, or equivalent
  • experience using a source-code-control tool (CVS, SVN, etc.)
  • strong oral and written communication skills
  • experience with a widely-used relational database, and comfort writing SQL queries by hand (ideally MySQL, but PostgreSQL, Oracle, SQL Server also ok)



Desired Experience (the more the better):

  • J2EE application servers (especially Tomcat, JBoss) and EJBs
  • core java (multi-threading, performance analysis/optimization, JVM configuration)
  • messaging systems and SOA architectures (TCP/IP-level protocols, web services)
  • design patterns for OO development
  • comfort with UML and/or ability to write and understand high-level software design documents
  • experience with the MVC architectural pattern and at least one Java-based MVC framework (Struts, Spring, etc.)
  • an object-data binding framework for Java (Hibernate, JDO, etc.)
  • sysadmin experience on a linux distribution or other unix OS
  • general networking experience
  • experience with production web application environments and web servers, especially Apache
  • javascript experience, particularly experience with AJAX toolkits
  • experience supporting a live web application in production



No recruiters - we already work with ones we want to work with. I repeat no recruiters or head-hunters etc. Only candidates should respond.

Please send a cover letter, resume and approximate desired salary to: careers@traveltripper.com

For more info on the company and the position, see the full job posting here:
http://www.meetup.com/ny-tech/messages/boards/thread/9017120/#35357662

Friday, April 16, 2010

Generics in UiBinder



Generics!

One of the most exciting things about GWT is that you get to use Java. And one of the most exciting things about Java is that you get to use Generics.

 




UiBinder!

Another great thing about GWT is the UiBinder, a tool that makes it really easy to create and (most importantly) modify and maintain ui layouts.

 




For a long time, though, I was stuck, because I was creating a bunch of fancy UI widgets that used Generics, but I didn't know how to specify them in my .ui.xml files.

There wasn't any mention of generics in the official google ui:binder tutorial, so I just sort of assumed it was impossible. As a workaround, I created <g:SimplePanel> instances in the .ui.xml files, and then filled them dynamically in the corresponding java files when calling createAndBindUi().

The other day, though, I was surfing through our app's DOM via Firebug (thank you OOPHM!) and I was getting a little annoyed at all the extra DIVs that were being created due to the wrapping SimplePanel instances.

So I looked a little deeper and I found a hit on the "google-web-toolkit" google code page entitled GWT UIBinder Use Cases.



Comment by rjrjr@google.com, Dec 13, 2009

@johan.rydberg, generics support is anemic, trying only not to break things. You can't specify generics in your ui.xml file, and you'll need to instantiate your Table in your owner class.

I'm pretty sure this should work (making some presumptions about your typed Table class):

 ui:field='rowTypeTable' />
@UiField(provided = true)

final Table<RowType> rowTypeTable = new Table<RowType>() {}




Very happily, I don't have a single thing to add here, the solution above works perfectly, no modifications needed.

Probably would be a good addition to the UiBinder tutorial page on the gwt homepage, but in the meantime, I figure putting it up here might help others who hit this same problem.





Friday, January 8, 2010

Too Many StyleSheets

In building our app, the approach I used towards styling has very much been "shortest route to dogfood"[1].

To that end, every time I created a new UI widget, I would just create an empty css file for it and dump in any necessary style rules (for whatever reason, at the time this seemed the fastest way to do it).

That worked nice and dandy, until I got up to about 30 stylesheets. Suddenly, GWT hosted mode was no longer loading all of my styles, things were looking funny. I did a little experimentation and found that it was always loading precisely *31* stylesheets and then stopping. Wierd.

I wrote a post on the GWT forum about it, to see if anyone else had come across this limitation.

Within a couple of hours, Thomas Broyer wrote back that this was actually a well-known limitation of IE (the browser on which hosted mode is based).

Ha! Thanks Thomas!

Lesson learned, case closed. Path to dogfood hindered but not blocked. "I'll just keep going for now, knowing that I have to fix this later".



Two months later, GWT 2.0 is out and I'm going back through all my code, yanking out reams of boilerplate code thanks to the tremendously powerful and sexy UIBinder.

Just fo[sic] fun, I try loading the app in IE to see how it likes one of my newly-restyled widgets, and....



Runtime Error!


00:35:22.000 [ERROR] Unable to load module entry point class com.traveltripper.stargazer.client.Stargazer (see associated exception for details)
java.lang.AssertionError: null at com.google.gwt.dom.client.StyleInjector$StyleInjectorImplIE.injectStyleSheet(StyleInjector.java:132) at com.google.gwt.dom.client.StyleInjector.flush(StyleInjector.java:358) at com.google.gwt.dom.client.StyleInjector.access$1(StyleInjector.java:343) at com.google.gwt.dom.client.StyleInjector$1.execute(StyleInjector.java:195) at com.google.gwt.core.client.impl.SchedulerImpl$Task$.executeScheduled$(SchedulerImpl.java:50)
...


Sadly, the error in and of itself told me nothing... I had to actually open the StyleInjector.java file and hunt down to line 132.

And there it was, my old friend. Too many stylesheets! Google actually prevents you from breaking the css limit -- via an assertion failure.

Technically, my path to the dog food is still unblocked -- it only gives me this runtime error when I load the app in IE. But I think now's probably a good time to go back and do things the right way.

Hopefully this helps someone out there who might run into this same error.



[1] A phrase which I learned from my ex-colleague-extraordinaire Chris Schmidt, and which I discovered only today, searching for links, is *not* actually a common expression but rather something he must have made up. It is, however, pretty self-explanatory: it basically means doing whatever is the fastest, easiest thing you can do to get a job done.