Matt RaibleMatt Raible is a writer with a passion for software. Connect with him on LinkedIn.

The Angular Mini-Book The Angular Mini-Book is a guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.

Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with Spring Boot and use security best practices like HTTPS and a content security policy.

For book updates, follow @angular_book on Twitter.

The JHipster Mini-Book The JHipster Mini-Book is a guide to getting started with hip technologies today: Angular, Bootstrap, and Spring Boot. All of these frameworks are wrapped up in an easy-to-use project called JHipster.

This book shows you how to build an app with JHipster, and guides you through the plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks so you understand the underpinnings of your great application.

For book updates, follow @jhipster-book on Twitter.

10+ YEARS


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.
You searched this site for "form". 326 entries found.

You can also try this same search on Google.

Devoxx4Kids - Denver: Introduction to Hardware Concepts with littleBits

Devoxx4Kids I'm pleased to announce the second meeting of the Denver Chapter of Devoxx4Kids is now open for registration. It's a two hour class titled Introduction to Hardware Concepts with littleBits and will be taught by Denver's own Tack Mobile. To learn more about littleBits, see http://littlebits.cc. If you or your company would like help by donating a Workshop Set, please contact me.

The class will be held on Saturday, November 22nd, from 10am - 12pm at Assembly Workspace. Cost is $10, but you'll get that back in the form of a t-shirt. Age requirement is 9-18 and kids should have basic computer skills (copy/paste, opening applications, etc.).

I'd like to thank Juan Sanchez for reaching out to me about this class and inspiring his company (and workspace) to make it all happen. It's been great working with you and your team Juan!

When I started Devoxx4Kids Denver, I was hoping to host a class or two per year. Our first meetup in May was a wild success. After taking the summer off to relax, I started looking for more speakers in early October. The response has been great and we'll have another class about GreenFoot on December 13th. We're even in the planning stages for another session on NAO Humanoid Robot programming in Q1 2015.

If you'd like to get involved with Denver's Devoxx4Kids, please join our meetup group.

Posted in General at Oct 30 2014, 08:17:21 AM MDT 1 Comment

This site now powered by Java 8, Tomcat 7 and Wufoo Forms

I recently upgraded this site to use the latest version of Apache Roller. It was a minor release (5.0.3), but I figured I'd document the steps in case "early onset" comes soon. First of all, to download raibledesigns.com and get it running locally, I perform the following steps:

  1. Backup everything using ~/bin/backup.sh on raibledesigns.com
  2. scp backup file to local hard drive and expand
  3. Copy ROOT, skins and repository directories to local webapps
  4. Make sure activation, mail, mysql and jta JARs are in $CATALINA_HOME/lib
  5. Copy roller-custom.properties from raibledesigns.com's $CATALINA_HOME/lib
  6. Copy context files from hosted $CATALINA_HOME/conf/Catalina to local directory
  7. Import database and change roller-custom.properties to match local credentials

Next, to upgrade to the latest Roller release, I do the following:

  1. Download latest Roller release and expand
  2. Copy JARs (from WEB-INF/lib) to existing install (to upgrade dependencies)
  3. Delete any lower-versioned JARS from WEB-INF/lib directory
  4. Copy JSPs (from WEB-INF/jsps) to existing install
  5. Run database migration scripts from WEB-INF/classes/dbscripts
  6. Use a diff tool (like SmartSynchronize) to compare new vs. existing
  7. Test and troubleshoot (if there's startup errors)

This process has worked well for the last 10 years, and it's been in my head the whole time. It's bound to escape someday.

Contact Form Enhancements
In addition to upgrading Roller, I also upgraded Tomcat 6 to Tomcat 7.0.52. In doing so, I found Jakarta's Mailer Taglib doesn't work with Tomcat 7. As you can tell from the aforementioned thread, I've known this for several years. That's the only thing that's stopped me from upgrading Tomcat the past couple years.

[Read More]

Posted in Roller at Apr 09 2014, 07:37:59 AM MDT Add a Comment

Devoxx4Kids - Denver Chapter Begins!

Devoxx4Kids I'm happy to announce the first meeting of the Denver Chapter of Devoxx4Kids is now open for registration. It's a two hour class titled Introduction to Server-Side Minecraft Programming and will be taught by Denver's own Scott Davis. The class will be held on May 3rd, from 10am - 12pm at Thrive's Cherry Creek location, where we can comfortably fit 20 students. Cost is $10, but you'll get that back in the form of a t-shirt. Age requirement is 9-18 and kids should have basic computer skills (copy/paste, opening applications, etc.). Minecraft experience will certainly help too.

I'd like to thank Daniel De Luca for his initial assistance with getting Devoxx4Kids setup in Denver and Arun Gupta for starting Devoxx4Kids USA. Arun has been a great help in getting things going and answering my questions over the last few months. Of course, none of it would be happening without Scott Davis or Thrive. If you join us on May 3rd, you'll see that Scott is an awesome teacher and Thrive has some incredible facilities.

My initial goal with Devoxx4Kids in Denver is to host a class or two this year. If there's enough demand, we can expand. For now, we're starting small and seeing where it takes us. If you're interested in teaching a future class, please let me know. We'd love to teach the kids a number of skills, from Scratch to NAO Humanoid Robot programming to building things with Arduino and Raspberry Pi.

Posted in Java at Apr 08 2014, 10:59:29 AM MDT Add a Comment

You shouldn't have to worry about front end optimization

After writing yesterday's article on optimizing AngularJS apps with Grunt I received an interesting reply from @markj9 on Twitter.

I clicked on the provided link, listened to the podcast (RR HTTP 2.0 with Ilya Grigorik) and discovered some juicy bits at around 27:00. The text below is from the podcast's transcript at the bottom of the page.

[Read More]

Posted in The Web at Jan 16 2014, 01:49:03 PM MST 5 Comments

A Webapp Makeover with Spring 4 and Spring Boot

A typical Maven and Spring web application has a fair amount of XML and verbosity to it. Add in Jersey and Spring Security and you can have hundreds of lines of XML before you even start to write your Java code. As part of a recent project, I was tasked with upgrading a webapp like this to use Spring 4 and Spring Boot. I also figured I'd try to minimize the XML.

This is my story on how I upgraded to Spring 4, Jersey 2, Java 8 and Spring Boot 0.5.0 M6.

When I started, the app was using Spring 3.2.5, Spring Security 3.1.4 and Jersey 1.18. The pom.xml had four Jersey dependencies, three Spring dependencies and three Spring Security dependencies, along with a number of exclusions for "jersey-spring".

Upgrading to Spring 4
Upgrading to Spring 4 was easy, I changed the version property to 4.0.0.RC2 and added the new Spring bill of materials to my pom.xml. I also add the Spring milestone repo since Spring 4 won't be released to Maven central until tomorrow.

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>${spring.framework.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<repositories>
    <repository>
        <id>spring-milestones</id>
        <url>http://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>
[Read More]

Posted in Java at Dec 11 2013, 12:47:15 PM MST 7 Comments

Developing with AngularJS - Part IV: Making it Pop

Welcome to the final article in a series on my experience developing with AngularJS. I learned its concepts, beat my head against-the-wall with and finally tamed it enough to create a "My Dashboard" feature for a client. For previous articles, please see the following:

The last mile of development for the My Dashboard feature was to spice things up a bit and make it look better. We hired a design company to come up a new look and feel and they went to work. Within a week, we had a meeting with them and they presented a few different options. We picked the one we liked the best and went to work. Below are screenshots that I used to implement the new design.

My Dashboard - New Design My Dashboard with Show More

[Read More]

Posted in The Web at Sep 12 2013, 10:54:29 AM MDT 7 Comments

Upgrading Grails from 2.0 to 2.2

Grails In preparation for my Grails vs. Play Smackdown at Devoxx France next week, I recently upgraded my Grails version of Happy Trails from Grails 2.0.3 to Grails 2.2.1. I ran into a few issues along the way and figured I'd document them here to help others out.

Fixing the source
The first issue I ran into was Spock and Groovy 2 incompatibilities.

| Resolving plugin JAR dependencies
| Error WARNING: Dependencies cannot be resolved for plugin [mail] due to error: startup failed:
Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at jar:file:/Users/mraible/.grails/ivy-cache/org.spockframework/spock-core/jars/spock-core-0.7-groovy-1.8.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation  because of exception org.spockframework.util.IncompatibleGroovyVersionException: The Spock compiler plugin cannot execute because Spock 0.7.0-groovy-1.8 is not compatible with Groovy 2.0.7. For more information, see http://versioninfo.spockframework.org

I posted the problem to StackOverflow and got a response almost immediately. While this pull request helped me quite a bit, it was ultimately caused by my vision: I had two "geb-spock" dependencies listed in BuildConfig.groovy with different groupIds.

At this point, I also moved all my plugin dependencies from application.properties to BuildConfig.groovy.

The next problem I ran into was a unit test and functional tests failing. The unit testing issue was caused by my Direction model not being in the tests @Mock annotation. After I added it, validation kicked and I recognized my test was invalid. I added @Ignore and continued.

The functional test seemed to be seemed to be caused by Geb and it trying to use the Chrome Driver. One of my tests didn't work with the default HtmlUnitDriver, so I used the ChromeDriver for the one test.

| Running 11 spock tests... 6 of 11
| Failure:  signup as a new user(happytrails.AuthenticatedUserSpec)
|  org.openqa.selenium.WebDriverException: Unable to either launch or connect to Chrome. Please check that ChromeDriver is up-to-date. Using Chrome binary at: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 45.66 seconds
Build info: version: '2.27.0', revision: '18259', time: '2012-12-05 11:30:53'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.8.2', java.version: '1.7.0_04'
Driver info: org.openqa.selenium.chrome.ChromeDriver
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:187)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:533)
    at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:216)
    at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:111)
    at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:115)
    at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:161)
    at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:107)
    at happytrails.AuthenticatedUserSpec.signup as a new user(AuthenticatedUserSpec.groovy:25)

Even when running "grails -Dgeb.env=chrome test-app", this still happened. This was caused by the fact that I had GebConfig.groovy in test/functional/happytrails. Move it to test/functional solved the problem. I also discovered that I know longer needed Chrome to get this test to pass. Apparently, the HtmlUnitDriver has issues with Grails 2.2, but it seems to work for me.

After getting the Geb configuration fixed, I ran into a functional test failure:

| Running 11 spock tests... 5 of 11
| Failure:  click signup link(happytrails.AuthenticatedUserSpec)
|  org.openqa.selenium.ElementNotVisibleException: Element must be displayed to click (WARNING: The server did not provide any stacktrace information)

Even though I could see the "signup" link when I ran "grails run-app", I could see that it didn't show up when running tests in Chrome. This turned out to be caused by an extraneous <div class="nav-collapse"> I had in my main.gsp. Removing it solved the problem. It's strange that this never showed up with Grails 2.0. My only guess is that Geb someone didn't look at the visibility of the element.

The last testing-related issue I ran into was a InvalidElementStateException:

| Running 11 spock tests... 7 of 11
| Failure:  add new route to region(happytrails.AuthenticatedUserSpec)
|  org.openqa.selenium.InvalidElementStateException: Element must be user-editable in order to clear it. (WARNING: The server did not provide any stacktrace information)

I was able to fix this by changing AddRoutePage.groovy from:

static content = {
    createButton(to: ShowRoutePage) { create() }
    name { value("Name") }
    distance { value("Distance") }
    location { value("Location") }
}

To:

static content = {
    createButton(to: ShowRoutePage) { create() }
    form { $("form") }
}

And then referencing name, distance and location accordingly (form.name, etc.) in AuthenticatedUserSpec.groovy.

CloudBees
After I had everything working locally, I logged into Jenkins on CloudBees. Since I hadn't used it in a while, I had to wait a bit while my Jenkins server was re-commissioned. Once it was up, I tried to select Grails 2.2.1 to build with, but found it wasn't available. After a tweeting this, I learned about Grails Wrapper, found that the latest Grails Jenkins plugin supported it and got everything working. I later discovered that CloudBees does support Grails 2.2.1, I just needed to setup another Grails installation to automatically download and install 2.2.1.

Heroku
The last two issues I ran into were with Heroku. Since I was upgrading everything, I wanted Grails to build/run under Java 7 and use Servlet 3. I changed the appropriate properties in BuildConfig.groovy, configured Heroku and deployed. No dice.

Error Compilation error: startup failed:
Invalid commandline usage for javac.
javac: invalid source release: 1.7
Usage: javac  
use -help for a list of possible options

Sidenote: I tried building with Java 8 on CloudBees, but discovered the searchable plugin doesn't support it.

Compile error during compilation with javac.
/scratch/jenkins/workspace/Happy Trails - Grails 2/work/plugins/searchable-0.6.4/src/java/grails/plugin/searchable/internal/compass/index/DefaultUnindexMethod.java:94: error: reference to delete is ambiguous
                    session.delete(query);
                           ^
  both method delete(CompassQuery) in CompassOperations and method delete(CompassQuery) in CompassIndexSession match

As far as Servlet 3, it was pretty obvious that the Jetty version Heroku uses for Grails doesn't support it. Therefore, I reverted back to Servlet 2.5.

java.lang.NoClassDefFoundError: javax/servlet/AsyncContext
	at org.codehaus.groovy.util.LazyReference.getLocked(LazyReference.java:46)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2444)

I sent the Java 7 issue to Heroku Support a few days ago but haven't heard back yet.

Summary
While upgrading Grails from 2.0 to 2.2 wasn't as easy as expected, it is understandable. After all, Grails 2.2 ships with Groovy 2.0, which has a bunch of new features itself. All the issues I ran into were fairly easy to solve, except for Java 7 on Heroku. But hey, what do you expect from a free hosting service?

If you're at Devoxx France next week, I look forward to sharing our research on Grails 2.2.1 vs. Play 2.1.0.

Posted in Java at Mar 22 2013, 09:16:37 AM MDT 2 Comments

The HTML5 Roadshow Rocks!

Canyonland's Sunset Road by Trish of McGinity Photo

In early February, as I was creating my Modern Java Web Developer presentation, I came across a training event that was similarly named. Since I happened to know the instructor, I shot him off an email asking more about it. He promptly replied a week later with an intriguing description. The following sentence really stood out for me:

They are NOT beginning workshops -- newbie information is easily found online, in books, at UG meetings, etc. They are targeted at working professionals who want to take their game to the next level.

The other thing that really struck me about this training was it was à la carte; meaning you could pick and pay for just the days you wanted to attend. Scott gave me a two-for-one deal and I signed up for the following workshops:

Normally, attending a training course would have an opportunity cost for me. However, since I work remotely and it doesn't matter where I work, I decided to work from the class. It turned out to be a great idea because it had the same feel of a productive day at the coffeeshop, but it was a coffeeshop full of knowledge. Instead of looking up and doing some people watching or getting distracted by social media, I would look up and learn something new. I actually ended up getting more done in those two training classes than I normally do at my LoDo Office.

Advanced JavaScript
The Advanced JavaScript workshop was taught by Kyle Simpson. This was my first time meeting Kyle and I was immediately impressed by his resume, especially his worked on Firefox Developer Tools for 9 months credentials. He started out talking about good JavaScript documentation on sites such as MDN and Principles of Writing Consistent, Idiomatic JavaScript. Tip: append "mdn" to any searches for JavaScript topics and you're likely to get better results. Not only that, but MDN is a wiki so you can improve it too. From there, we moved onto DOM Events, event propagation (e.g. bubbling vs. capturing), event management, scopes, this, closures and design patterns. It was a very deep dive into JavaScript and I enjoyed every minute of it.

Airplane-Mode HTML5
The Airplane-Mode HTML5 workshop was taught by Scott Davis (his site is currently down, should be fixed next week). Scott talked about many things I was already familiar with, but I still managed to learn a bunch of new tips and tricks. He started by having us install Node, volo and creating projects. He showed how package.json is the JS project's equivalent of pom.xml.

Next, he plunged into viewports, orientation and how to use CSS3 media queries. I've always used min-device-width and max-device-width in my media queries, so orientation: portrait and orientation: landscape was a useful tip. He taught us about CSS3's pseudo-classes (esp. for validation) and pointed us to the Forward Thinking Form Validation article. We learned about using findmebyIP.com and how it can be a useful tool for finding your browser's capabilities, particularly when you're in a black box environment (e.g. a browser on a TV). I knew about Modernizr, but wasn't aware of has.js for JavaScript feature detection.

Scott talked about many more topics, from HTML5 forms and mobile links to geolocation and maps. He ended the day talking about local storage and application cache.

The Good
First of all, the price was perfect at around $250 per day. The best part for me was that I learned more than I expected to. Not only that, but I didn't have to endure any opportunity cost to attend these workshops. There were times I wish I didn't have to work, but it was cool to have "learning stuff" as a distraction rather than social media.

The Bad
The Location. I ride my bike to work year-round and only sit in traffic a few times per year. So I know I'm biased. The location was in Louisville and while it should be only a 30-minute commute, I spent 2 hours in the car each day. Once I got there, the facility was great, the internet was fast and the lunch choices were splendid.

To see if the HTML5 Roadshow is coming to your town, checkout ThirstyHead on Eventbrite or follow them on Twitter.

Posted in The Web at Mar 14 2013, 03:16:58 PM MDT Add a Comment

Integrating GWT into AppFuse

I've been interested in integrating GWT into AppFuse ever since I blogged about it 4 years ago. A few months after that post, I wrote about Enhancing Evite.com with GWT and Grails. After Evite, I had a gig near Boston where I developed with GXT for the remainder of the year. When all was said and done, I ended up spending a year with GWT and really enjoyed my experience. I haven't used it much since.

GWT is scheduled to be integrated into AppFuse in version 4.0. That's quite a ways off. The good news is you might not have to wait that long, thanks to Iván García Sainz-Aja. Iván let us know about his work a couple weeks ago in an email to the appfuse-dev mailing list.

It's still work in progress but it has already most of AppFuse functionality..

If you want to give it a try

https://github.com/ivangsa/appfuse.git

the quickest way to have a go would be

web/gwt> mvn -P gwtDebug -Dgwt.inplace=true gwt:compile jetty:run  

at the moment it still requires this fork of gwt-bootstrap to be compiled first

https://github.com/ivangsa/gwt-bootstrap.git

It needs a lot of testing yet but it's getting quite there

As you can imagine, I was very excited to hear about Iván's work. So I cloned his repo, built gwt-bootstrap locally and checked it out. Functionality wise, it was great! However, when I dug into the source code, I found a whole lotta code.

To see how the GWT flavor compared to the other implementations in AppFuse, I created a cloc report on the various web frameworks in AppFuse. I'm sure these reports could be adjusted to be more accurate, but I believe they give a good general overview. I posted some graphs that displays my findings in visual form.

Lines of Java Number of Files

When I sent this to the mailing list, Ivan responded that it was a lot of code and estimated 12 new files would be needed to CRUD an entity. This sure seems like a lot to me, but he defended this yesterday and noted that his implementation follows many of GWT's latest best practices: MVP pattern, Activities and Places, EventBus, Gin and Guice. He also shared a wiki page with explanations and diagrams of how things work.

The reason I'm writing this post is to get more feedback on this implementation. First of all, does GWT really require this much code? Secondly, are there other GWT implementations that reduce a lot of the boilerplate? SmartGWT, Vaadin* and Errai come to mind.

If you were starting a new GWT project and using AppFuse, how would you want it implemented?

* Vaadin 7 claims it can be used as a drop-in replacement for GWT. I tried replacing the gwt-servlet and gwt-user dependencies with Vaadin's, but it didn't work.

Posted in Java at Mar 07 2013, 06:49:28 PM MST 7 Comments

What's the best way to compare JVM Web Frameworks?

I've been comparing web frameworks ever since 2004. It was the first time I'd ever proposed a talk for a conference. ApacheCon was in Vegas that year and my buddy Bruce suggested I speak at it. I submitted the talk, got accepted and went to work learning the frameworks I was talking about. At the time, I had a lot of Struts experience and I'd made a good living learning it, consulting on it and blogging about it. However, there was a new kid on the block (Spring MVC) that was garnishing attention and some other frameworks (WebWork and Tapestry) that had a lot of high praise from developers. I was inspired to learn why so many people hated Struts.

Fast forward 8 years and I'm still comparing web frameworks. Why? Because there still seems to be a large audience that's interested in the topic. Witness InfoQ's Top 20 JVM Web Frameworks, which was one of their most-read articles for two months in a row. One of the beauties of the Java Community is that it's very diverse. There's tons of folks that are part of this community and, like it or not, several folks that are former Java Developers. However, these developers still seem to maintain an interest in the community and it's still one of the largest pools of talent out there. Java is still quite viable and only seems to be getting better with age.

So the topic of web frameworks on the JVM is still hot, and I still like to write about it. For those of you still enthusiastic about the topic, you're in luck. The two best websites for the Java Community, InfoQ and DZone (formerly Javalobby) are still very interested in the topic too!

[Read More]

Posted in Java at Jan 09 2013, 08:29:17 AM MST 6 Comments