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 "maven". 270 entries found.

You can also try this same search on Google.

Modularizing GWT Applications with GWT-Maven

Last week, I spent some time modularizing the GWT application I'm working on. By modularizing, I mean splitting the code from one GWT module into a "core" and "webapp" module. The reason for doing this was so the "core" module could be used by another GWT application. Creating GWT Modules is fairly straightforward, but it wasn't as intuitive as expected when using the gwt-maven-plugin.

The hardest part of moving the code was figuring out how to run tests in the new "core" module. After getting it all working, it seems easy enough. Hopefully this post will make it easy for others. Here's the steps I'd recommend:

  1. Convert your GWT project into a multi-module project where you have a top-level pom.xml and two sub-modules (e.g. gwt-core and gwt-webapp).
  2. Do the normal single-to-multi-project Maven stuff like declaring the <parent> element in the modules and moving plugins/dependencies to the top-level pom.xml.
  3. Refactor your gwt-webapp project to push down all shared classes (and their tests) to gwt-core.
  4. In the gwt-core project, include *.xml and *.java in your JAR so GWT can extract/compile the source code when building gwt-webapp.
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.java</include>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
    
  5. In gwt-core/src/main/java, create a Core.gwt.xml that references the modules you'd like to use in all your applications. For example:
    <module>
        <inherits name="com.google.gwt.user.User"/>
        <inherits name="com.google.gwt.i18n.I18N"/>
        <inherits name="com.extjs.gxt.ui.GXT"/>
        <inherits name="pl.rmalinowski.gwt2swf.GWT2SWF"/>
    </module>
    
  6. Now the tricky part begins, mostly because of how the gwt-maven plugin currently works. In src/test/java, create a NoOpEntryPoint.gwt.xml that inherits your Core module and defines an EntryPoint.
    <module>
        <inherits name="com.company.app.Core"/>
        <entry-point class="com.company.app.NoOpEntryPoint"/>
    </module>
    
  7. Create a NoOpEntryPoint.java class in the same directory as NoOpEntryPoint.gwt.xml.
    public class NoOpEntryPoint implements EntryPoint {
        
        public void onModuleLoad() {
            // do nothing
        }
    }
    
  8. In any class that extends GWTTestCase (I usually create a parent class for all tests), reference the NoOpEntryPoint in the getModuleName() method.
        @Override
        public String getModuleName() {
            return "com.company.app.NoOpEntryPoint";
        }
    
  9. Lastly, in the gwt-maven plugin's configuration (in gwt-core/pom.xml), reference the NoOpEntryPoint in <compileTargets>, a non-existent file in <runTarget> and only the "test" goal in the executions.
    <plugin>
        <groupId>com.totsp.gwt</groupId>
        <artifactId>maven-googlewebtoolkit2-plugin</artifactId>
        <version>2.0-beta26</version>
        <configuration>
            <compileTargets>
                <value>com.company.app.NoOpEntryPoint</value>
            </compileTargets>
            <runTarget>com.company.app.NoOpEntryPoint/doesntexist.html</runTarget>
            <logLevel>INFO</logLevel>
            <style>OBF</style>
            <noServer>false</noServer>
            <extraJvmArgs>-Xmx512m</extraJvmArgs>
            <gwtVersion>${gwtVersion}</gwtVersion>
            <testFilter>*GwtTestSuite.java</testFilter>
            <testSkip>${skipTests}</testSkip>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <goal>test</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    

The results of modularizing your application are beneficial (shared code) and detrimental (you have to mvn install gwt-core whenever you make changes in shared classes). If you know of a way to configure the gwt-maven plugin to read sources from both gwt-core and gwt-webapp in hosted mode, I'd love to hear about it.

Posted in Java at Mar 23 2009, 10:36:08 AM MDT 11 Comments

GXT's MVC Framework

For the past couple of months, I've been developing a GWT application using a mix of plain ol' GWT and GXT widgets. When I first started developing it, I didn't know how to best organize my code and separate the logic. The solution I came up with was to adopt some sort of MVC framework. Since I was already using GXT, I opted for GXT's lightweight MVC implementation.

As mentioned in Testing GWT Applications, GXT's MVC doesn't have much documentation. The best reference documentation seems to be Christian's Getting started with Ext-GWT: The Mail reference application.

Page Transitioning with Dispatcher
After working with GXT MVC for a couple months, I'm still not sure I fully understand how navigation and event dispatching works. The biggest point of confusion for me is how to best use GXT's Dispatcher class.

The problem with Dispatcher is it has a two methods that seem to do the same thing.

  • forwardEvent (4 variations)
  • dispatch (3 variations)

In addition to these methods in Dispatcher, there's two fireEvent methods in GXT's View class. According to my calculations, that means there's 9 different options for transitioning from one view to the next. Which one is best to use?

From what I've learned, I think it's best to use fireEvent in Views and forwardEvent in Controllers and other widgets. IMO, dispatcher should never be used except in your HistoryListener's implementation onHistoryChanged method. The important thing to realize about this method is it should only work if the View's Controller is registered for the event.

  protected void fireEvent(AppEvent event) {
    Controller c = controller;
    while (c != null) {
      if (c.canHandle(event)) {
        c.handleEvent(event);
      }
      c = c.parent;
    }
  }

However, fireEvent seems to work even when the View's Controller isn't registered for that event. This is because onHistoryChanged gets called in the EntryPoint. For experienced GXT MVC users, does this navigation handling mesh with your findings?

The most important thing for navigation to work successfully is enabling History support. The next section talks about how to do this effectively.

Enabling History Support
To help explain things better, I created a simple GWT MVC Example application and used Maven to create an archetype with it. You can create a project from the archetype using the following command:

mvn archetype:create -DarchetypeGroupId=org.appfuse.archetypes \
-DarchetypeArtifactId=gwt-mvc -DarchetypeVersion=1.0-SNAPSHOT \
-DgroupId=com.mycompany.app -DartifactId=myproject \
-DremoteRepositories=http://oss.sonatype.org/content/repositories/appfuse-snapshots

To enable history support in this application, I implemented HistoryListener in my EntryPoint (Application.java) and added the following logic to initialize:

// If the application starts with no history token, redirect to 'home' state
String initToken = History.getToken();
if (initToken.length() == 0) {
    History.newItem(HistoryTokens.HOME);
}

// Add history listener
History.addHistoryListener(this);

// Now that we've setup our listener, fire the initial history state.
History.fireCurrentHistoryState();

In this example, HistoryTokens is a class that contains all the URLs of the "views" in the application.

public class HistoryTokens {
    public static final String HOME = "home";
    public static final String CALENDAR = "calendar";
    public static final String NOTES = "notes";
    public static final String SEARCH = "search";
}

In order to make URLs like http://localhost:8080/#calendar go to the calendar view, the following logic exists in the onHistoryChanged method.

        Dispatcher dispatcher = Dispatcher.get();

        if (historyToken != null) {
            if (historyToken.equals(HistoryTokens.HOME)) {
                dispatcher.dispatch(AppEvents.GoHome);
            } else if (historyToken.equals(HistoryTokens.CALENDAR)) {
                dispatcher.dispatch(AppEvents.Calendar);
            } else if (historyToken.equals(HistoryTokens.NOTES)) {
                dispatcher.dispatch(AppEvents.Notes);
            } else if (historyToken.equals(HistoryTokens.SEARCH)) {
                dispatcher.dispatch(AppEvents.Search);
            } else {
                GWT.log("HistoryToken '" + historyToken + "' not found!", null);
            }
        }

Controllers are registered in the EntryPoint as follows:

        final Dispatcher dispatcher = Dispatcher.get();
        dispatcher.addController(new CalendarController());
        dispatcher.addController(new HomeController());
        dispatcher.addController(new NotesController());
        dispatcher.addController(new SearchController());

Controllers respond to events they're registered for. This is done in their constructor:

    public CalendarController() {
        registerEventTypes(AppEvents.Calendar);
    }

In order for navigation to work, you have to create links with history tokens1. For example, here's a link from the HomeView class:

	Hyperlink notesLink = new Hyperlink("Notes", HistoryTokens.NOTES);
	notesLink.addClickListener(new ClickListener() {
	    public void onClick(Widget widget) {
	        Dispatcher.get().fireEvent(AppEvents.Notes);
	    }
	});

You'll notice in this example, I'm using Dispatcher's fireEvent method. If I wanted to pass some data with your event, you'll need to use forwardEvent. Here's an example from CalendarView:

    Button submit = new Button("Submit");

    submit.addSelectionListener(new SelectionListener<ButtonEvent>() {
        public void componentSelected(ButtonEvent ce) {
            AppEvent<Date> event = 
                new AppEvent<Date>(AppEvents.GoHome, date.getValue(), HistoryTokens.HOME);
            Dispatcher.forwardEvent(event);
        }
    });

In this example, you could also use Dispatcher.dispatcher(), but I believe this will cause the transition to happen twice because the onHistoryChanged method gets called too. This doesn't matter for the most part, except when you start to use DispatcherListeners.

Hopefully this article has helped you understand how GXT's MVC framework works. I'm interested in learning how other GWT MVC frameworks work. If you've used one, I'd love to hear about your experience.

Friday Fun Test
Here's a test for those interested in digging into the GXT MVC example. There's a bug in this application that prevents something from happening. I'll buy a drink for the person that finds the bug and I'll buy two drinks for the person that comes up with a solution. ;-)

1. If you use the default constructor on Hyperlink and use setText(), make sure to call setTargetHistoryToken() too. If you don't, a blank history token will be used and # causes the browser to scroll to the top before a page transition happens.

Posted in Java at Mar 13 2009, 11:48:41 AM MDT 25 Comments

Nexus is a kick-ass Repository Manager

I started my current gig at the end of last year. I've been enjoying the work and especially the project infrastructure we've been using. We're using the usual suspects: JIRA, Confluence, Hudson and Subversion. We're also using a couple new ones, namely sventon and Nexus. For building, we're using Maven and Ivy (as a Grails plugin).

Nexus I'm writing this post to talk about Nexus and how much I've enjoyed using it. I like Nexus for two reasons: it's aesthetically pleasing and it's well-documented. Another reason I really dig it is because I haven't had to touch it since I first configured it. Software that just keeps on humming is always fun to work with.

Initially, I remember having some issues setting up repositories. I also remember solving them after learning how groups work.

In addition to on-the-job, I've started to use Nexus more and more in my open source life. With the help of Jason van Zyl, I recently moved AppFuse's repository to Sonatype's oss.sonatype.org. I also noticed there's a Nexus instance for Apache projects. If that's not enough, you can get Nexus Pro free if you're an open source project.

Personally, the open source version of Nexus seems good enough for me. While the Staging Suite looks nice, I think it's possible to do a lot of similar things with good communication. After all, it's not going to free you from having to wrestle with the maven-release-plugin.

Next week, I'm helping to polish and document our entire release process (from dev → qa → production). If you have any advice on how to best perform releases with Maven, Grails and/or Nexus, I'd love to hear about it. My goal is extreme efficiency so releases can be done very quickly and with minimal effort.

Posted in Java at Mar 05 2009, 11:59:02 PM MST 13 Comments

GWT and AppFuse

Someone recently sent me the following e-mail asking about GWT integration in AppFuse.

I see from your blog that you're spending some time with GWT at the moment. What's your plan, are you going to integrate GWT as another UI Option for AppFuse?

The reason I'm asking is that I actually checked out all of the AppFuse code from the svn repository yesterday, with the intention of starting off adding some GWT stuff in there. My intention was to start by getting a basic Maven archetype together for GWT as an AppFuse UI.

However, if you're planning on doing this yourself in the near future, then there's no point in me starting doing it, I'd have to learn how to write archetype's for a start (not that it looks too difficult) but you'd obviously do it much quicker.

Being a good open-source developer, I moved the discussion to the developer mailing list and replied there:

It's likely I'll create a version of AppFuse Light with GWT, but I doubt I'll do it in the near future. I hope to release AppFuse 2.1 first (which will include "light" archetypes). I wouldn't get your hopes up in waiting for me to do the work. However, I'd be happy to assist you in doing it. AppFuse Light is now modular and uses the AppFuse backend.

http://raibledesigns.com/rd/entry/appfuse_light_converted_to_maven

Here's how I believe GWT should be integrated:

  1. Create an appfuse-ws archetype that serves up RESTful services (http://issues.appfuse.org/browse/APF-897).
  2. Create an appfuse-gwt archetype that consumes those services. This archetype would contain a proxy servlet that allows #1 to be on a separate host/port.

In addition to #1, I hope to convert the Struts 2 and Spring MVC archetypes to use those frameworks' REST support.

For #2, we could use SmartGWT or GXT. SmartGWT might be better since Sanjiv is a committer on this project. ;-)

I know I've been slacking on AppFuse development, but it is ski season and running to work seems to drain my late-night coding ambitions. With that being said, I'm committed to getting AppFuse 2.1 released by JavaOne (hopefully sooner). I figure it's a good week's worth of work and I'll probably have to do it late at night to find the time. That's OK though, I usually really start to enjoy it once I get into it.

Posted in Java at Mar 04 2009, 10:50:26 PM MST 5 Comments

GWTTestSuite makes builds faster, but requires JUnit 4.1

Earlier this week, I spent some time implementing GWTTestSuite to speed up my project's build process. In Hudson, the project was taking around 15 minutes to build, locally it was only taking 5 minutes for mvn test. In IDEA, I could run all the tests in under a minute. While 15 minutes isn't a long time for a build to execute, a co-worker expressed some concern:

Does Maven have to run GWT test and individual Java processes? (See target/gwtTest/*.sh) This arrangement and the overhead of JVM launches is another reason why builds take so long. As we add more GWT tests we are going to test that LinkedIn record for the slowest build ever.

After this comment, I started looking into GWTTestSuite using Olivier Modica's blog entry as a guide. It was very easy to get things working in IDEA. However, when I'd run mvn test, I'd get the following error:

Error: java.lang.ClassCastException

No line numbers. No class information. Zilch. After comparing my project's pom.xml with the one from the default gwt-maven archetype, I noticed the default used JUnit 4.1, while I had the latest-and-supposedly-greatest JUnit 4.4. Reverting to JUnit 4.1 fixed the problem. Now Hudson takes 3:15 to execute the build instead of 15 minutes.

The reason for this blog post is this doesn't seem to be documented anywhere. Hopefully other developers will find this entry when googling for this issue.

Related to making GWT faster, I also added the following line to my Application.gwt.xml file:

<set-property name="user.agent" value="safari" />

This dropped the gwt:compile time from 1 minute to 25 seconds. As explained in the documentation, you can use the "user.agent" setting to only generate one JS file for your app instead of 4. The strange thing about adding this setting was I pretty much forgot about it since everything seemed to work fine on both Safari and Firefox. When I started testing things in IE6, I started seeing a lot of JavaScript errors. After debugging for an hour or so, I realized this setting was there, removed it, and everything started working great in all browsers.

Now if I could just figure out how to use safari-only for development, but remove the line when building the WAR. Suggestions welcome.

Posted in Java at Feb 27 2009, 11:58:12 AM MST 6 Comments

Enhancing your GWT Application with the UrlRewriteFilter

Last week, I spent some time trying to change the location of my cache/nocache HTML files in my GWT project. I started the project with the gwt-maven-plugin's archetype. The message I posted to the gwt-maven Google Group is below.

Rather than having my application's HTML file in src/main/java/com/mycompany/Application.html, I'd like to move it to src/main/webapp/index.html. I tried copying the HTML and adding the following to my index.html, but no dice:

<meta name="gwt:module" content="com.mycompany.Application"/>

Is this possible with the gwt-maven-plugin? I'd like to have my main HTML and CSS at the root of my application.

The good news is I figured out a solution using the UrlRewriteFilter that 1) allows hosted mode to work as usual and 2) allows your app to be served up from the root URL (/ instead of /com.company.Module/Application.html). Here's the urlrewrite.xml that makes it all possible.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCENGINE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.0//EN"
        "http://tuckey.org/res/dtds/urlrewrite3.0.dtd">

<urlrewrite>
    <rule>
        <from>^/$</from>
        <to type="forward" last="true">/com.mycompany.app.Application/Application.html</to>
    </rule>
    <rule>
        <from>/index.html</from>
        <to type="forward" last="true">/com.mycompany.app.Application/Application.html</to>
    </rule>
    <-- This last rule is necessary for JS and CSS files -->
    <rule>
        <from>^/(.*)\.(.*)$</from>
        <to type="forward">/com.mycompany.app.Application/$1.$2</to>
    </rule>
</urlrewrite>

If you're using the gwt-maven plugin, this file goes in src/main/webapp/WEB-INF. In addition, you'll need to add the following to your web.xml.

    <filter>
        <filter-name>rewriteFilter</filter-name>
        <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>rewriteFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Finally, add the UrlRewriteFilter dependency in your pom.xml:

    <dependency>
        <groupId>org.tuckey</groupId>
        <artifactId>urlrewritefilter</artifactId>
        <version>3.1.0</version>
    </dependency>

Please let me know if you have any questions.

Update: Jeff posted an alternative configuration that allows you to eliminate the last rule in urlrewrite.xml, as well as use the beloved mvn jetty:run command. To use cleaner WAR packaging and the Jetty plugin, add the following to your pom.xml:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
        <webappDirectory>
            ${project.build.directory}/${project.build.finalName}/com.mycompany.app.Application
        </webappDirectory>
    </configuration>
</plugin>
<plugin>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>maven-jetty-plugin</artifactId>
    <version>6.1.14</version>
    <configuration>
        <webAppConfig>
            <contextPath>/</contextPath>
            <baseResource implementation="org.mortbay.resource.ResourceCollection">
                <resourcesAsCSV>
                    ${basedir}/src/main/webapp,
                    ${project.build.directory}/${project.build.finalName}/com.mycompany.app.Application
                </resourcesAsCSV>
            </baseResource>
        </webAppConfig>
        <scanIntervalSeconds>3</scanIntervalSeconds>
        <scanTargets>
            <scanTarget>${basedir}/src/main/resources</scanTarget>
            <scanTarget>${basedir}/src/main/webapp/WEB-INF</scanTarget>
            <scanTarget>
                ${project.build.directory}/${project.build.finalName}/com.mycompany.app.Application
            </scanTarget>
        </scanTargets>
    </configuration>
</plugin>

Then you can trim your urlrewrite.xml down to:

<urlrewrite>
    <rule>
        <from>^/$</from>
        <to type="forward" last="true">/Application.html</to>
    </rule>
    <rule>
        <from>/index.html</from>
        <to type="forward" last="true">/Application.html</to>
    </rule>
</urlrewrite>

Of course, you could also change the welcome-file in your web.xml or use index.html and the <meta http-equiv="REFRESH"> option. Personally, I have so much affection for the UrlRewriteFilter that I like having it in my project. I'm sure I'll need it someday.

Thanks Jeff!

Posted in Java at Feb 23 2009, 05:02:29 PM MST 13 Comments

Testing GWT Applications

Last week, I did some research on GWT, how to test it and code coverage options for tests that extend GWTTestCase. The reason I did this is because I've found that most of the GWT tests I write have to extend GWTTestCase and I'd like to have code coverage reports. Read below for more information on my findings for testing GWT classes.

There are quite a few articles about testing GWT applications. Here are a few samples:

The main gist of these articles is that you should structure your code to make the core functionality of your application testable without having to depend on GWTTestCase.

All of them also advocate using an MVC or MVP (Model View Presenter) pattern. Currently, I'm using GXT and its MVC Framework. Unfortunately, GXT's MVC doesn't have much documentation. The good news is there is a good article that explained enough that I was able to refactor my project to use it.

The unfortunate side of this refactoring was I discovered that classes that extend GXT's MVC Framework have to be tested with GWTTestCase. The downside to extending GWTTestCase is there is it's difficult to create code coverage reports.

GWT's issue 799 has some patches that should make code coverage possible. I tried to implement code coverage with Eclipse and EclEmma using this README, but failed. In the process, I discovered an issue with Eclipse 3.4 and JUnit on OS X. Reverting to Eclipse 3.3 solved this problem, but I was still unable to make EclEmma work with GWT.

After failing with Eclipse, I tried to use the emma-maven-plugin. I was also unable to get this to work, with my findings documented in this thread.

Finally, I did have some luck with getting IDEA's built-in code coverage feature working. However, after getting it to work once, it failed to work for the rest of the day and I haven't had success since.

Code Coverage and GWT
Because of these issues with GWT 1.5 and code coverage, I think I'll wait until GWT 1.6 to worry about it. The good news is 1.6 M1 was released last Friday. If continuing to use GWTTestCase becomes an issue, I may write my own MVC Framework that doesn't use classes that call native JavaScript. Hopefully GXT MVC's framework will provide a good example.

In addition to trying to get code coverage working, I used the internets to figure out how run GWT tests inside of Eclipse and IDEA. I don't remember the resources I used, but hopefully this up-to-date documentation will help others. The nice thing about using an IDE to run these tests is they typically execute much faster.

Running GWT Tests in Eclipse
You should be able to run most of your GWT tests from within Eclipse using the following steps.

  1. Right-click on a test that extends GWTTestCase and go to Run As > JUnit Test. It's likely you will see the error message below.
    Invalid launch configuration: -XstartOnFirstThread not specified.
    
    On Mac OS X, GWT requires that the Java virtual machine be invoked with the
    -XstartOnFirstThread VM argument.
    
    Example:
      java -XstartOnFirstThread -cp gwt-dev-mac.jar com.google.gwt.dev.GWTShell
    
  2. To fix this error, go to Run > Open Run Dialog. Click on the Arguments tab and add the following values. The 2nd value is to increase the amount of memory available to the test and avoid an OOM error.
    -XstartOnFirstThread -Xmx512M
  3. When you re-run the test, you will probably see the following error:
    com.google.gwt.junit.JUnitFatalLaunchException: The test class 'org.richresume.client.home.HomeControllerGwtTest' 
    was not found in module 'org.richresume.client.Application'; no compilation unit for that type was seen
      at com.google.gwt.junit.JUnitShell.checkTestClassInCurrentModule(JUnitShell.java:193)
      at com.google.gwt.junit.JUnitShell.runTestImpl(JUnitShell.java:628)
      at com.google.gwt.junit.JUnitShell.runTest(JUnitShell.java:150)
      at com.google.gwt.junit.client.GWTTestCase.runTest(GWTTestCase.java:219)
    
  4. To fix this, open the Run Dialog again, click on the Classpath tab and click on User Entries. Click on the Advanced button and select Add Folders. In the Folder Selection dialog, select your source and test directories (e.g. src/main/java and src/test/java).
  5. Run the test again and you should see a green bar in your JUnit tab.
  6. To create a JUnit configuration that runs all tests, duplicate the previously mentioned run configuration. Then change the name to "All Tests" and select the 2nd radio button to run all tests in the project.
  7. Click Run to execute all the tests in the project.

Running GWT Tests in IDEA
You should be able to run your GWT tests from within IDEA using the following steps.

  1. Right-click on a test that extends GWTTestCase and go to Run "TestNameGwtTes...". It's likely you will see the error message below.
    Invalid launch configuration: -XstartOnFirstThread not specified.
    
    On Mac OS X, GWT requires that the Java virtual machine be invoked with the
    -XstartOnFirstThread VM argument.
    
    Example:
      java -XstartOnFirstThread -cp gwt-dev-mac.jar com.google.gwt.dev.GWTShell
    
  2. If you get a compiler error instead, you may need to add the GWT Facet to your project. To do this, right-click on your project's top-most folder in the left pane. Select Module Settings > Facets and enable GWT for your module.
  3. To fix the -XstartOnFirstThread issue, go to Run > Edit Configurations. Add the following values to the VM Arguments field. The 2nd value is to increase the amount of memory available to the test and avoid an OOM error.
    -XstartOnFirstThread -Xmx512M
    NOTE: If you still get a compiler error, see this page for a possible solution.
  4. Run the test again and you should see a green bar in your Run tab.
  5. To create a JUnit configuration that runs all tests, duplicate the previously mentioned run configuration. Then change the name to "All Tests" and change the Test configuration to search for tests in the whole project.
  6. Run the new configuration to execute all the tests in the project.

Testing GWT applications isn't as straightforward as writing JUnit tests, but I do believe it's getting better. If you have any additional tips and tricks, please let me know.

Posted in Java at Feb 09 2009, 03:27:36 PM MST 6 Comments

What's the best Java Hosting Solution?

A friend recently asked me who I'd recommend for a Java hosting provider. Since I get asked this question every-so-often, it seemed appropriate to post my answer here.

  1. KGB Internet - I use KGB for this site. I have my own JVM and have full control over what I want to install. I can control Tomcat versions and upgrade as needed. I don't know if I'd recommend him for a business site as he can take up to 12 hours to respond to requests.
  2. Kattare - These guys will give you your own Tomcat instance and seem to have reasonable prices. They do seem to take quite some time to respond to requests (24-48 hours). I have a free instance that I use for a non-profit, so that could be the reason.
  3. Contegix - These guys are far-and-away the best company for Java-based hosting. They're not cheap though. However, they have the best customer service in the business - often responding to e-mails in less than a minute.

Do you agree with these recommendations? If not, who do you recommend for Java hosting and why?

Posted in Java at Feb 07 2009, 10:21:28 AM MST 38 Comments

Choosing an Ajax Framework

This past week, my colleagues and I have been researching Ajax Frameworks. We're working on a project that's following SOFEA-style architecture principles and we want the best framework for our needs. I'm writing this post to see 1) if you, the community, agree with our selection process and 2) to learn about your experiences with the frameworks we're evaluating. Below is the process we're following to make our choice.

  1. Choose a short list of frameworks to prototype with.
  2. Create an application prototype with each framework.
  3. Document findings and create a matrix with important criteria.
  4. Create presentation to summarize document.
  5. Deliver document, presentation (with demos) and recommendation.

For #1, we chose Ext JS, Dojo, YUI and GWT because we feel these Ajax libraries offer the most UI widgets. We also considered Prototype/Scriptaculous, jQuery and MooTools, but decided against them because of their lack of UI widgets.

For #2, we time-boxed ourselves to 3 days of development. In addition to basic functionality, we added several features (i.e. edit in place, drag and drop, calendar widgets, transitions, charts, grid) that might be used in the production application. We all were able to complete most of the functionality of the application. Of course, there's still some code cleanup as well as styling to make each app look good for the demo. The nice thing about doing this is we're able to look at each others code and see how the same thing is done in each framework. None of us are experts in any of the frameworks, so it's possible we could do things better. However, I think it's good we all started somewhat green because it shows what's possible for someone relatively new to the frameworks.

For #3, we're creating a document with the following outline:

Introduction

Ajax Framework Candidates
(intro and explanation)

  Project Information
  (history)
  (license / cost)
  (number of committers)
  (support options)
  (mailing list traffic (nov/dec 2008))

Matrix and Notes

Conclusion

For the Matrix referenced in the outline above, we're using a table with weights and ranks:

Weight Criteria Dojo YUI GWT Ext JS Notes
# Important Criteria for Customer 0..1 0..1 0..1 0..1 Notes about rankings

Our strategy for filling in this matrix:

  • Customer adjusts the weight for each criteria (removing/adding as needed) so all weights add up to 1.
  • We rank each framework with 0, .5 or 1 where 0 = doesn't satisfy criteria, .5 = partially satisfies, 1 = satisfies.

The list of criteria provided to us by our client is as follows (in no particular order).

  • Quality of Documentation/Tutorials/Self Help
  • Browser support (most important browsers/versions based on web stats)
  • Testability (esp. Selenium compatibility)
  • Licensing
  • Project health/adoption
  • Performance
  • Scalability
  • Flexibility/extensibility
  • Productivity (app dev, web dev)
  • Richness of widget/component library
  • Charting capability
  • Ability to create new widgets
  • Match to existing Java team skill-set
  • Ease of deployment (on Ops, QA, Users)
  • Degree of risk generally
  • Ability to integrate with existing site (which includes Prototype)
  • Easy to style with CSS
  • Validation (esp. marking form elements invalid)
  • Component Theme-ing/Decoration
  • CDN Availability (i.e. Google's Ajax Libraries API or Ext CDN)

What do you think? How could this process be improved? Of course, if you have framework answers (0, .5 or 1) for our matrix, we'd love to hear your opinions.

Posted in Java at Jan 08 2009, 09:36:22 PM MST 39 Comments

2008 - A Year in Review

In 2005 and 2006, I did "A Year in Review" entries. 2007 was the year I got divorced, which probably motivated me to write a bit less. This year I'm back and ready to spend the next few hours writing, copying/pasting and linking like a madman. Hope you enjoy!

Workin' on the Feedlot 2008 was the year I traveled the world and developed a true passion for skiing. In January, my good friend Jason Miller moved back to Denver after quitting his job at Bear Stearns in NYC. We spent the first weekend in Nebraska working on Cletus's feedlot. The next week, my car stereo got stolen and I wondered if my bad knee would make it through the ski season (the good news is not only did I ski the rest of the season, but my knee healed itself over the summer).

Abbie and Jack on Green Mountain At the end of January, the kids and I hiked to the top of Green Mountain and Don Brown made Maven not suck. Then I wondered if there was room for both Rails and Grails at a company and quickly learned both.

February started fantastically with a 14" Powder Day at Steamboat. I wondered if there is no "best" web framework and reviewed Grails and Rails books. After spending an awesome weekend in Tahoe, I took the kids on The Ski Train and learned more about Selenium at Google.

Breathtaking Miller and Vial Lake Tahoe - Last Run

This brings us to one of my favorite posts of all time. On February 28th, Jack got a bead stuck in his nose. After taking him to the ER and paying $800, we found out magic recipe for bead removal is to "hold one nostril and give him a CPR-type breath/blow into his mouth". The reason I love the post so much is it's solved the problem for other frantic parents when they Google for "bead stuck in nose". Whenever I get a new comment, it always makes me smile.

March started out with a Powder Day at Whistler. I thoroughly enjoyed the rest of the weekend with good friends Jarvis and Korn Dog. After returning to Denver, I was allowed to blog about building a UI Frameworks Team at LinkedIn and posted my thoughts on Grails vs. Rails.

View from Our Condo In mid-March, I achieved an all-Mac family and traveled to Lake Chelan for my sister's birthday. Shortly after, The AppFuse Primer was released. At the end of the month, I attended TSSJS in Vegas and moderated a Web Framework Smackdown.

In April, the LinkedIn Denver office opened and we all celebrated by attending the Rockie's Home Opener. The ski season came to an end and I wrote a howto for configuring Apache with mod_proxy and SSL on OS X. Then I discovered the JavaOne parties and wrote about running Spring MVC Web Applications in OSGi.

April ended with 82°F and May started with snow. I attended JavaOne (or at least the parties), released AppFuse 2.0.2 and figured out how to do extensionless URLs with the UrlRewriteFilter. The kids and I spent an afternoon in Rocky Mountain National Park and I did some coding in my backyard.

Jack's Special Rock Nice Trail Beautiful Smile Here's Hoping for another run in October

On Memorial Day, I enjoyed a liver-wrenching, Rockies-filled weekend with my sister her girlfriend Mya and Mr. Miller. I also contemplated making AppFuse Struts 2-specific.

June started with some mountain bike riding, planning some excellent vacations and getting a dream machine. I rode the annual trip to Big Head Todd at Red Rocks with Matt and Bruce. I took the kids on their first camping trip for Father's Day and had a blast. It took us several hours to find the campsite and my car kept starting all night long. It's sure to be a family tradition from now on.

Catchin' Bugs

The next weekend, I attended the American Craft Beer Fest in Boston. To end the month, I embarked upon Raible Road Trip #12 with Abbie, Jack and my Dad.

Grand Tetons In July, the bus project began and I posted pictures of the trip to Montana. This year, I hope to spend the whole month of July at the cabin. I bought an iPhone (one of my best technology-related purchases to date). OSCON was fun but the week after wasn't.

Nice 'n Snug August revealed my favorite birthday present. I didn't blog much the rest of the month, revealing why later.

Jack on his 4th Birthday Jack's Birthday Weekend was an outstandingly fun mixture of old friends and good Colorado beer. In September, I went to see the bus at MotorWorks, Abbie lost her first tooth and co-workers and I performance tested Memcached.

What followed was wonderful. Miller and I headed to Oktoberfest for the Best. Vacation. Ever. We still talk about how much fun we had on that vacation. October finished with the Colorado Software Summit and a hunting trip to the cabin.

November was a crazy month. I got laid off and celebrated Abbie's birthday on the same day. Jack got a mohawk and I traveled coast-to-coast in the same week. To close the month, I announced what's next and headed to Costa Rica.

Costa Rica, courtesy of Rob Misek

I had a fantastic time in Costa Rica and was impressed to see Abbie is a blue skier shortly after. I did a Dojo/Comet Research Project for a week and enjoyed the location of my newest client last week. A small adventure turned into a scary adventure and I enjoyed telling my stories to fellow Java Enthusiasts in Portland.

Phew! It's been quite a year. For 2009, I'm still hoping for what I tweeted shortly after Costa Rica. I'd like to visit 3 foreign countries, take 3 months of vacation and spend 1 month in Montana. I have technology goals too, but those aren't nearly as much fun to dream about. ;-)

Happy New Year!

Posted in Roller at Dec 31 2008, 04:56:32 PM MST 2 Comments