748 篇文章 0 订阅

I’ve had an opportunity recently to work on a product that needed an RIA web interface, and I chose my recent favorite tool for this, Vaadin. The services for this project needed to be highly scalable, and lent themselves well to functional techniques, so I selected Scala as my language of choice. I build my projects with Maven, for reasons I won’t go into right now, and I do much of my JVM-language work in Intellij’s excellent IDEA IDE.

Given these tools, I found a way to facilitate very rapid development of web UI’s, and I thought I’d pass it along.

Another technique I use, which I’ll expound on later, is creating “dummy” implementations of all of my backing services for my application. The “real” implementations are written as OSGi services, in separate modules from my UI. The UI is packaged as a war, but is also OSGi aware, with a bundle activator. This activator only gets called if the war is deployed into an OSGi container, and not otherwise. This allows the app to select which implementation of the services it uses – the “dummy” ones when it’s deployed outside of OSGi, and the “real” ones when they’re available.

This means I can use the handy Maven jetty plugin to quickly spin up my application and test it on my local workstation, without needing all of the dependencies (like a data store and such) of my real services. That’s good, in that I can get my “cycle time” down to a few seconds, where “cycle time” is the time between making a change and actually being able to test it in my browser.

We can do better, though.

I’m using Scala as my language of choice for building the UI as well, as it works just fine with Vaadin (and with everything else in the JVM ecosystem, for that matter, which is why I didn’t choose a non-JVM language – but that’s yet another rant).

I compile my Scala with the Maven scala plugin – here’s where the next handy bit comes into play. Turns out the Scala plugin has a goal called “cc”, for continuous compilation. Using this, I can fire up Maven with a “mvn scala:cc” command, and leave it running. Then I also use the “mvn jetty:run” command in another window to fire up the web application, and leave it running as well.

Here’s my configuration for the Scala plugin:

 01 <plugin>
 02                 <groupid>org.scala-tools
 03                 <artifactid>maven-scala-plugin
 04                 <version>2.9.1
 05                 <executions>
 06                     <execution>
 07                         <goals>
 08                             <goal>compile
 09                             <goal>testCompile
 10                         
 11                     
 12                 
 13                 <configuration>
 14                     <scalaversion>\${scala.version}
 15                     <args>
 16                         <arg>-target:jvm-1.5
 17                     
 18                 
 19             

And for Jetty:

 01 <plugin>
 02                 <groupid>org.mortbay.jetty
 03                 <artifactid>maven-jetty-plugin
 04                 <version>6.1.9
 05                 <configuration>
 06                     <scanintervalseconds>10
 07                     <webappsourcedirectory>src/main/webapp
 08                     <jettyconfig>jetty.xml
 09                     <userrealms>
 10                         <userrealm implementation="org.mortbay.jetty.security.HashUserRealm">
 11                             <name>file
 12                             <config>realm.properties
 13                         
 14                     
 15                     <stopkey>stop
 16                     <stopport>8889
 17                 
 18             

Now I go back to my IntelliJ and start coding. Every time IntelliJ saves (which it does automatically unless you tell it not to), the Scala plugin compiles the files. This generates a new .class file, which the Jetty plugin (well, technically, Jetty itself) detects, and in response, reloads the running classes for the web application.

Net effect is that I can make my change and by the time I switch back to the browser, my new code is running. I test my change, emit the appropriate profanity, and go back to editing, all within a second or two.

This has profound effects on how you develop a UI, which every dynamic language aficionado knows (e.g. like Ruby/Rails or Python/Django). You don’t hesitate to experiment, and you get to see the visual effect of your changes right away. The good news is that I get to do this with my language of choice, and with all the power of the JVM ecosystem to support it.

The technique is not perfect – I’ve found that if you edit some resources or webapp files (images and such), it’s possible the Jetty plugin doesn’t “see” the change. Of course, two things help with that considerably: first, it’s lightning-fast to just Control-C the jetty plugin task and re-launch it, and second a Vaadin app generally doesn’t use many resources, unlike JSP or many other frameworks that make extensive use of templates.

Once in a while I’ve found the scala:cc task will report that it’s lost it’s connection to the “fsc” (fast scala compiler) background process – again, quickly control-c-ing the task and starting it again solves the problem every time.

Overall, I can crank UI out pretty darn quick with this method, and given that I can TDD even my UI code using Vaadin, I find the overall combination very effective and efficient.

• 0
点赞
• 0
收藏
• 0
评论
10-25
07-31 2742
03-23 1万+
03-26 5561
06-19 2万+
02-01 248

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助