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 "matt". 663 entries found.

You can also try this same search on Google.

Integrating Selenium with Maven 2

I spent some time this past week integrating Selenium with Maven 2. This post is designed to show you how to do this in your Maven 2 projects.

First of all, there were two types of testing scenarios I wanted to make possible. The first was to allow HTML-based tests that web designers could create and run with Selenium IDE. As far as I know, Selenium IDE is capable of recording and exporting Java-based tests (powered by TestNG or JUnit), but I don't believe it's capable of playing them back. So for Java Developers, I wanted to allow them to write their tests in Java.

To get Maven to run HTML-based tests, the easiest way seems to be using the <selenese> Ant task. I tried Mavenium as well, but it 1) doesn't use the latest version of Selenium RC and 2) reports success when tests fail. Below is a Maven profile that I'm using in an AppFuse-based project to run HTML tests.

<profiles>
    <profile>
        <id>integration-test</id>
        <activation>
            <property>
                <name>!maven.test.skip</name>
            </property>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.cargo</groupId>
                    <artifactId>cargo-maven2-plugin</artifactId>
                    <version>0.3-SNAPSHOT</version>
                    <configuration>
                        <wait>${cargo.wait}</wait>
                        <container>
                            <containerId>${cargo.container}</containerId>
                            <!--home>${cargo.container.home}</home-->
                            <zipUrlInstaller>
                                <url>${cargo.container.url}</url>
                                <installDir>${installDir}</installDir>
                            </zipUrlInstaller>
                        </container>
                        <configuration>
                            <home>${project.build.directory}/${cargo.container}/container</home>
                            <properties>
                                <cargo.hostname>${cargo.host}</cargo.hostname>
                                <cargo.servlet.port>${cargo.port}</cargo.servlet.port>
                            </properties>
                        </configuration>
                    </configuration>
                    <executions>
                        <execution>
                            <id>start-container</id>
                            <phase>pre-integration-test</phase>
                            <goals>
                                <goal>start</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>stop-container</id>
                            <phase>post-integration-test</phase>
                            <goals>
                                <goal>stop</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <artifactId>maven-antrun-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>launch-selenium</id>
                            <phase>integration-test</phase>
                            <configuration>
                                <tasks>
                                    <taskdef resource="selenium-ant.properties">
                                        <classpath refid="maven.plugin.classpath"/>
                                    </taskdef>
                                    <selenese suite="src/test/resources/selenium/TestSuite.html"
                                              browser="*firefox" timeoutInSeconds="180" port="5555"
                                              results="${project.build.directory}/selenium-firefox-results.html"
                                              startURL="http://${cargo.host}:${cargo.port}/${project.build.finalName}/"/>
                                </tasks>
                            </configuration>
                            <goals>
                                <goal>run</goal>
                            </goals>
                        </execution>
                    </executions>
                    <dependencies>
                        <dependency>
                            <groupId>ant</groupId>
                            <artifactId>ant-nodeps</artifactId>
                            <version>1.6.5</version>
                        </dependency>
                        <dependency>
                            <groupId>org.openqa.selenium.server</groupId>
                            <artifactId>selenium-server</artifactId>
                            <version>0.9.1-SNAPSHOT</version>
                        </dependency>
                    </dependencies>
                </plugin>
            </plugins>
        </build>
    </profile>
    <profile>
        <id>selenium-ie</id>
        <activation>
            <os>
                <family>windows</family>
            </os>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-antrun-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>launch-selenium</id>
                            <phase>integration-test</phase>
                            <configuration>
                                <tasks>
                                    <taskdef resource="selenium-ant.properties">
                                        <classpath refid="maven.plugin.classpath"/>
                                    </taskdef>
                                    <selenese suite="src/test/resources/selenium/TestSuite.html"
                                              browser="*firefox" timeoutInSeconds="180" port="5555"
                                              results="${project.build.directory}/selenium-firefox-results.html"
                                              startURL="http://${cargo.host}:${cargo.port}/${project.build.finalName}/"/>
                                    <selenese suite="src/test/resources/selenium/TestSuite.html"
                                              browser="*iexplore" timeoutInSeconds="180" port="5555"
                                              results="${project.build.directory}/selenium-ie-results.html"
                                              startURL="http://${cargo.host}:${cargo.port}/${project.build.finalName}/"/>
                                </tasks>
                            </configuration>
                            <goals>
                                <goal>run</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

The above setup will allow you to run Selenium tests in Firefox, and in IE as well when you're on Windows. I tried to get Safari to work on the Mac, but it just opens Safari and hangs.

HTML tests are great for non-programmers, but what about developers that prefer Java and want test reports to be included in the surefire-plugin's reports? That's easy enough. First of all, put your tests in a particular package so they can be excluded from the normal testing cycle. I used a webapp.selenium package. I configured the surefire-plugin to exclude these tests:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <excludes>
            <exclude>**/selenium/*Test.java</exclude>
        </excludes>
    </configuration>
</plugin>

Then I added the newly released selenium-maven-plugin to my "integration-test" profile and configured surefire to run the Selenium Java tests.

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>selenium-maven-plugin</artifactId>
    <version>1.0-beta-1</version>  
    <executions>
        <execution>
            <id>start-selenium</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>start-server</goal>
            </goals>
            <configuration>
                <background>true</background>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <executions>
        <execution>
            <id>surefire-it</id>
            <phase>integration-test</phase>
            <goals>
                <goal>test</goal>
            </goals>
            <configuration>
                <excludes>
                    <exclude>none</exclude>
                </excludes>
                <includes>
                    <include>**/selenium/*Test.java</include>
                </includes>
            </configuration>
        </execution>
    </executions>
</plugin>

Yeah, Maven can be quite verbose when configuring profiles. I contacted the Maven list to see if it's possible to simplify all this XML, but so far haven't found a solution.

If you'd like to see a pom.xml with the Selenium bits and a profile that runs both HTML and Java-based tests, click here (JavaScript needs to be enabled for this to work).

NOTE: I used 0.9.1-SNAPSHOT of Selenium Server because it solves issues with the latest version of Firefox.

This brings up a related question I asked on the AppFuse mailing list a couple of days ago:

Do you use the Canoo WebTests? If not, how do you do UI testing? If so, would you prefer Selenium?

If you've tried AppFuse 2.x and have an opinion, please add a comment. Personally, I like Selenium, but I like how Canoo WebTest can be somewhat friendly to designers and allow i18n testing with Ant's property file support. With Selenium, you have to use parse/replace or Java tests to do i18n testing. Then again, if you need to test a lot of Ajax functionality, it's likely that Selenium will work much better for you.

Posted in Java at Mar 09 2007, 10:35:04 AM MST 17 Comments

Java CMS Systems

Michael Levin is at the JavaPosse Roundup this week. Today, they're discussing Java CMS Systems. I recently had an e-mail discussion with a reader regarding Java-based CMS Systems. In hopes of getting these questions answered by Michael today, here's that thread:

Original E-Mail:
OpenCMS, Magnolia CE/EE, Atleap, Alfresco, Liferay.

Magnolia EE, Day Communique, Hannon Hill, Refresh, Vertical Site.

We are leaning towards Magnolia EE since we have a load balancer and two production server, but I bet we could hack in support in the community edition.

Any comments/recommendations?
-------- My response:
I'd check out Alfresco's new 2.0 WCM - just released last week. I haven't looked at many of the CMSes in a year or so, but I'm willing to bet that OpenCMS still has issues installing. I still like Drupal too and recommend it for folks just wanting a website they can edit.

In reality, my experience with CMS systems is outdated and you shouldn't consider me an authority. ;-)
-------- Thanks for the lead. We actually eliminated Alfresco, b/c I thought they were more of a portal.

The reason we were leaning towards Magnolia and Vertical Site was b/c of JSR 170 (which Alfesco claims to support).

I wonder about the scalability of JCR, do have an opinion?
-------- I don't have an opinion because I don't have much experience with it. It's supposed to be the JDBC of CMSs, so I imagine it's pretty scalable. However, it's pretty new, so I'm sure there will be growing pains. I know that Infoq.com uses Magnolia as their backend (and WebWork as their frontend), so obviously it scales well for them.

What are your thoughts on Java-based CMS Systems? Comments from experienced developers appreciated more than vendor pitches. ;-)

Posted in Java at Mar 08 2007, 08:45:50 AM MST 14 Comments

RE: Jetty Ant Plugin

It looks like Jetty has a new Plugin for Ant. If you've used the Jetty Maven Plugin, you know this is a slick way to quickly deploy your application. For those of you wondering about Tomcat, there's a similar Tomcat Maven Plugin that supports tomcat:run and tomcat:run-war. However, it's still in Mojo's sandbox.

I'm pumped to see this Jetty task for Ant because I've been thinking a lot about creating an exploded, full-source archetype for AppFuse 2.0. Of course, it's probably possible to start Jetty and monitor your project for changes w/o this task - but it does seem to make things a fair amount easier. If we do a full-source archetype, it makes sense to support Ant as well - especially since we can probably re-use the build.xml from AppFuse Light.

This brings up a related questions I asked on the AppFuse mailing list yesterday:

A couple of questions for folks using (or planning to use) 2.x:

1. As far as archetypes go, are you using basic or modular?

2. If there was a 3rd type of archetype that included the full source (like AppFuse 1.x), would you use it over the existing basic or modular archetypes? If yes, I'm assuming upgrading is not that big of an issue for you?

If you've tried AppFuse 2.x and would like to answer these questions, please add a comment.

There's another questions about Selenium vs. Canoo WebTest in that post, but that's reserved for another entry where I'll talk about Selenium options in Maven 2.

Posted in Java at Mar 08 2007, 08:13:08 AM MST 3 Comments

Zero Configuration in Struts 2

Struts 2 has a nifty zero configuration feature. However, it's only useful for registering actions, not for automatically registering results. In other words, you still have to use an @Result annotation to tell your action what page to dispatch to. To use default view names instead of requiring @Result, you can use the Codebehind Plugin. Also, did you know Struts 2 will autowire your Spring dependencies? It's pretty slick.

What does this all mean? It means you can write your Struts 2 application without writing any XML. Of course, you can still use XML to tweak behavior, but with these plugins enabled, you won't have to.

IMO, these plugins should be combined into a single zero configuration feature.

Here's how you can enable Struts 2's Zero Configuration feature in AppFuse 2.0:

  1. Add a packageNames parameter to the "struts" filter in your web.xml:
    <filter>
        <filter-name>struts</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
        <init-param>
            <param-name>actionPackages</param-name>
            <param-value>com.company.newapp.webapp.action</param-value>
        </init-param>
    </filter>
    
  2. Add the Codebehind Plugin as a dependency in your pom.xml:
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-codebehind-plugin</artifactId>
        <version>2.0.6</version>
    </dependency>
    
  3. Add a struts.codebehind.pathPrefix constant in struts.xml for your default pages directory:
    <constant name="struts.codebehind.pathPrefix" value="/WEB-INF/pages/"/>
    

That's it - now you can code away without configuring anything!

How does this compare to other web frameworks in AppFuse? Tapestry has a similar feature, but Spring MVC and JSF don't. Spring MVC still requires you create a bean definition for Controllers and JSF requires you write a chunk of XML for each managed bean. Of course, if you know how to do something similar with Spring MVC or JSF, please let me know.

Posted in Java at Mar 07 2007, 05:19:18 PM MST 9 Comments

Artifactory - a new Maven 2 Repository Manager for Enterprises

From the Maven 2 user list:

We would like to announce the immediate availability of Artifactory, a Maven 2 enterprise proxy.

Artifactory offers advanced proxying, caching and security facilities to answer the needs of a robust, reproducible and independent build environment using Maven 2. It uses a JSR-170 Java Content Repository (JCR) for storage, which makes it extremely easy to manage searchable metadata, and provide extended features such as security, transacted operations, auditing, locking, etc.

Artifactory is distributed under APLv2 at http://artifactory.sourceforge.net. It is currently available as a downloadable archive, that can be run out of the box (with default settings). An install script to run it as a Linux service is also provided. A (limited) guest live demo is available at http://www.jfrog.org/artifactory (username/password is guest/guest).

You are welcome to give it a go!

Cheers,

Yoav Landman,
The Artifactory Team

So how does this compare to Archiva, Proximity and Maven Proxy? One user writes (formatted for better reading):

My experience so far:
  • Archiva: Alpha; doesn't work (random webdav deployment failures), loads of bugs, low rate of progress. Feels dead.
  • Proximity: Works; slightly confusing (don't like the separation of metadata); lots of new releases constantly; hard to configure (hacking around with spring config files) - our install takes *forever* to restart.
  • m2proxy: simple, but simple.
Fingers crossed that artifactory hits the sweet spot...

It's interesting to see that Artifactory's UI is powered by Wicket and Dojo. The demo seems kind of sluggish, but I don't believe this application is meant to handle more than 10 users at a time. For more information on Artifactory's features, see its introduction page.

It's great to see a (seemingly) good tool come out for internal repository management.

I spent a couple days last week analyzing the best open source continuous integration server for Maven 2 projects. Hudson turned out to be the clear winner with the best UI and easiest setup. It also actually worked, which is a lot more than I can say for Continuum. While I did get Continuum to work, it required turning on anonymous SVN (no, putting the username/password in the URL did not work). CruiseControl worked as well, but required config.xml knowledge, which sometimes scares admins. Pulse and Bamboo continue to be the best commercial Maven 2 testers, while TeamCity failed my 10-minute test (twice!). One of the features I was looking for was Trac integration and that only exists for CruiseControl and Continuum.

It's amazing to see projects like Continuum and Archiva. If they're any reflection of the Maven team's ability to develop software, that's frightening. My advice: discontinue both of these projects as they're a waste of anyone's time to even research them.

Update October 2009: Fast forward a couple years and I take back what I said about the Maven's team ability to develop good software. Nexus is a kick-ass Repository Manager.

Posted in Java at Mar 05 2007, 07:35:00 AM MST 24 Comments

Comparing Java Web Frameworks at ApacheCon Europe

It's been almost 2 1/2 years since I created and presented my "Comparing Web Frameworks" talk at ApacheCon 2004. It's hard to believe that was my first talk in front of a large audience. Before that conference, I posted a list of possible topics, as well as an outline a few days later. The most recent time I presented this talk was at Spring Forward 2006.

At this year's ApacheCon Europe, I'll be presenting Comparing Java Web Frameworks again. This time, I'll be adding Wicket and Stripes to the mix. I'm adding these two because they seem to be getting the most hype in Java developer's blogs. Of course, it would be great to add Grails, RIFE and Seam, but that's just too much to cover in an hour. Also, Grails is just Spring MVC and Seam uses JSF - so RIFE is the only one that stands out as unique. Here's the current session description:

One of the most difficult things to do (in Java web development) today is pick which web framework to use when development an application. The Apache Software foundation hosts most of the popular Java web frameworks: Struts, MyFaces, Tapestry and Wicket. This session will compare these different web frameworks, as well as Spring MVC and Stripes. It will briefly explain how each works and the strengths and weaknesses of each. Tips, tricks and gotcha's will be plentiful. Lastly, it will provide attendees with a sample application that utilizes all 6 frameworks, so they can compare line-by-line how the frameworks are different. This sample application will include the following features: sortable/pageable list, client and server-side validation, success and error messages as well as some Ajax functionality. The frameworks will be rated on how easy they make it to implement these features.

Over the next couple months, I'll try to post a revised outline so all the folks who care about a comparison like this can voice their opinions. I'll also be integrating Stripes and Wicket into AppFuse and AppFuse Light.

I'm still not sure about the name "AppFuse Light", but it's probably better than "AppFuse LE" which doesn't seem to convey the concept enough. The problem with "Light" is how to spell it (Bud Light vs. Miller Lite). The nice thing about AppFuse LE is we can shorten it to ALE. Regardless, you gotta love how it can all be related back to beer. ;-)

I've never been to Amsterdam before, so I'm definitely looking forward to this trip. My dad will be joining me, so I'll probably do more site-seeing that conference-going. If you're from the area, do you have any suggestions on what to do and where to stay? My dad has been pricing tickets and thinks we'd be better off flying into Frankfurt, spending a few days in Germany, and then arriving a day or two before my talk (on Friday). However, Queen's Day is the Monday of the conference and I've heard rumors it shouldn't be missed. I've got some Dutch and German in my blood, so it should be fun to visit my ancestral homeland.

Posted in Java at Feb 22 2007, 04:44:43 PM MST 12 Comments

Java is more complicated than .NET ... unless you use AppFuse

From Java to .NET, Back To Java Again, My Little Impression of The Two:

Having said all these, integration of various java projects together really do take a lot of Java people's time, it's no joke, but it's not desperate. For example, the open source project "AppFuse" does a fantastic job integrating various frameworks for us, I strongly encourage everyone to give it a shot and see how much time it saves you.

So which platform do I like? My impression is Java offers a lot flexibility and choices, but at the same time introduced the "Paradox of Choices", having so many things and integrate them together is no easy task, it simply overwhelm the human brains. .NET on the other hand is in a controlled environment, less choices, but easy to develop.

In other words: Java development is way more complicated than .NET ... unless you use AppFuse. ;-)

Posted in Java at Feb 20 2007, 09:25:15 PM MST 5 Comments

Database Profiles in AppFuse 2.0

Last night, I added several database profiles to AppFuse 2.0 and its archetypes. What does this mean? It means AppFuse should work out-of-the-box with several databases, including:

  • H2
  • HSQLDB
  • MySQL
  • PostgreSQL
  • SQL Server

For example, here's how to test a new AppFuse project works with H2:

mvn archetype:create -DarchetypeGroupId=org.appfuse -DarchetypeArtifactId=appfuse-basic-struts -DremoteRepositories=http://static.appfuse.org/repository -DarchetypeVersion=1.0-m4-SNAPSHOT -DgroupId=com.mycompany -DartifactId=myproject
Yeah, I wish there was a way to shorten this command (or prompt for choices) too.

After doing this, you can cd into the "myproject" directory and run mvn integration-test -Ph2. AppFuse 2.0 projects are configured for MySQL by default, so if you want to permanently activate one of these profiles, you can add the following between the <id> and <properties> section of the profile.

    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>

In addition to the profiles listed above, I tried to get Oracle Express and embedded Derby working. No dice on either one. I took a brief look at DB2 Express as well, but with a 400 MB download and 3 JARs required for its JDBC Driver - it seemed like a lot more trouble than it was worth.

Maven 2's build profiles are a powerful feature that we hope to make easy to use. For example, to test your new project with H2 and JBoss, you can simply run mvn integration-test -Ph2,jboss. Thanks to the power of Cargo, this will download JBoss 4.0.5, install it, and run all the Canoo WebTests within it. Of course, this will take a while the first time - especially since JBoss is a 77MB download. Fortunately, we allow you to change one small setting in your pom.xml and use an existing install instead.

Maven 2 is a kick-ass build/deploy/test tool once you figure it out. With AppFuse 2.0, we're doing all the "figuring out" for you. ;-)

NOTE: I would add more server profiles, but Cargo's Maven Plugin (version 0.2) has issues with Geronimo 1.1, Jetty 6.x and Resin 3.x. Strangely enough, Jetty's Maven Plugin version 6.0.0 works great, but 6.1.0 throws stack traces.

Update: Support for Oracle and Derby (in networked mode) has been added. We'll consider adding support for DB2 if IBM can figure out how to package their JDBC Driver into a single JAR.

Posted in Java at Feb 14 2007, 05:41:37 PM MST 27 Comments

Slick looking Confluence sites

You have to admit, both Wicket and Cayenne have nice looking websites. Did you know they're both backed by Confluence? Wicket has a Writing documentation page that explains how it works. Basically, they use the autoexport plugin to export their content to static files. If you configure this plugin to be invoked from a cron job, it's a great way to create a constantly updating dynamic-but-static site.

I believe there's a couple reasons Apache uses this setup: 1) it allows projects to customize the look and feel of their site w/o customizing how Confluence looks and 2) it reduces load on its servers since most content is served up statically. I've thought about using a similar setup for AppFuse's documentation, but I've run into a couple issues:

  • The autoexport plugin is pretty flaky. The latest release (0.13) doesn't work with Confluence 2.2.9. Strangely enough, the previous version (0.12) works fine. It looks like the author had a good run with this plugin when he created it (almost a year ago), but hasn't updated it since.
  • The dynamic tree menu doesn't get included in the export. If I could somehow include this tree (and the current theme) when exporting, it'd be very cool.
  • The new code macro works much better than the {code} macro, but it has exporting issues both with PDF and the autoexport plugin. I tried using the code macro, but it doesn't show any syntax highlighting when using an Adaptavist Builder theme.

Apache's setup for Confluence appears to be quite good. I wonder if we should use it for AppFuse? We don't have the bandwidth/load issues that they do - and we've managed to make the site look decent using Adaptavist Builder. I like having a single source of constantly changing documentation, rather than two sites, where one is static. I think this causes confusion for users if the documentation changes a lot. That being said, I would like to export the content for bundling and versioning with each release. I wonder if Atlassian is planning on fixing the new code macro exporting issue anytime soon?

Posted in Java at Feb 09 2007, 08:02:54 AM MST 5 Comments

AppFuse 2.0 M3 Released

The AppFuse team is pleased to announce the release of AppFuse 2.0 M3! This release marks a milestone in our documentation efforts. We've completed all of the web framework tutorials and ensured that all the archetypes work properly. Turkish language support was added and native2ascii was integrated so all i18n bundles should work properly.

The major things missing from this release are code generation (AppGen) and web services (XFire) support. We hope to add both of these before the final release.

AppFuse 2.0 is available as a Maven archetype. For information on creating a new project using this release, please see the QuickStart Guide.

The 2.0 series of AppFuse has a minumum requirement of the following specification versions:

  • Java Servlet 2.4 and JavaServer Pages (JSP) 2.0
  • Java 2 Standard Platform Edition (J2SE) 5.0

For more information, please see the 2.0 M3 Release Notes.

We appreciate the time and effort everyone has put toward contributing code and documentation, posting to the mailing lists, and logging issues. We also greatly appreciate the help from our sponsors, particularly Atlassian, Cenqua, Contegix, JetBrains, Java.net and KGBInternet. Without them, working on this project wouldn't be nearly as much fun. ;-)

Posted in Java at Feb 06 2007, 02:16:45 PM MST 16 Comments