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 "ant". 338 entries found.

You can also try this same search on Google.

Running Cargo from Maven

Yesterday, I integrated Cargo into our application so we could start/stop Tomcat before running our jWebUnit tests. I use Cargo in AppFuse and Equinox - which are both Ant-based. Since we're using Maven on our project, I had to do a bit of futzing to get Cargo integrated into Maven. I prefer to use the Ant tasks from Cargo than the programmatic API because it's nice to run your tests when you start Tomcat manually. If you use the programmatic API, and start/stop Tomcat in setUp()/tearDown() methods - your test will fail if Tomcat is already running.

Below is what I added to maven.xml. With this, we can run "maven test-web" to test our UI with Tomcat running or "maven test-tomcat" to start/stop Tomcat before running our tests. Now I just need to figure out the best way to configure the proper port in my jWebUnit test. I'll probably put it into project.properties and the read the value as part of my test. I've also included a "deploy" goal in this example to demonstrate an easy way to deploy to Tomcat.

    <property environment="env"/>
    <property name="maven.tomcat.home" value="${env.CATALINA_HOME}"/>

    <!-- deploy the directory created by war:webapp to tomcat/webapps -->
    <goal name="deploy" prereqs="war:webapp">
        <copy todir="${maven.tomcat.home}/webapps">
            <fileset dir="${maven.build.dir}">
                <include name="${pom.artifactId}/**"/>
            </fileset>
        </copy>
    </goal>

    <goal name="test-tomcat" prereqs="war:war"
        description="Starts Tomcat, runs jWebUnit tests, stops Tomcat">

        <taskdef resource="cargo.tasks" classpathref="maven.dependency.classpath"/>

        <cargo-tomcat5x homeDir="${maven.tomcat.home}"
            output="${maven.test.dest}/cargo.log" action="start" >
            <war warFile="${maven.war.build.dir}/${maven.war.final.name}"/>
            <configuration dir="${maven.test.dest}/tomcat5x">
                <property name="cargo.logging" value="high"/>
                <property name="cargo.servlet.port" value="8280"/>
            </configuration> 
        </cargo-tomcat5x>
        
        <attainGoal name="test-web"/>
        
        <cargo-tomcat5x homeDir="${maven.tomcat.home}" action="stop"/>
    </goal>

    <goal name="test-web" prereqs="test:compile" description="Runs JUnit tests">

      <taskdef name="junit"
        classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask"/>
      
        <mkdir dir="${maven.test.reportsDirectory}"/>
        <junit printsummary="no" errorProperty="test.failed" 
            failureProperty="test.failed">
            <classpath>
                <pathelement location="${maven.test.dest}"/>
                <pathelement location="${maven.build.dest}"/>
                <path refid="maven.dependency.classpath"/>
                <path location="web"/>
            </classpath>
            <formatter type="xml"/>
            <formatter type="brief" usefile="false"/>
            <batchtest todir="${maven.test.reportsDirectory}" if="testcase">
                <fileset dir="${maven.test.dest}">
                    <include name="**/*${testcase}*"/>
                    <exclude name="**/*TestCase.class"/>
                    <exclude name="**/*$*.class"/>
                </fileset>
            </batchtest>
            <batchtest todir="${maven.test.reportsDirectory}" unless="testcase">
                <fileset dir="${maven.test.dest}">
                    <include name="**/*WebTest.class"/>
                </fileset>
            </batchtest>
        </junit>

        <fail if="test.failed">
          Unit tests failed. For error messages, check the log files in
          ${maven.test.reportsDirectory}.</fail>
    </goal>

Posted in Java at Jan 15 2005, 02:15:05 PM MST 2 Comments

[DJUG] Testing and Handling Exceptions in the Web Tier

I'm attending Denver's JUG tonight, where Scott Davis is talking about Unit Testing the Web Tier. His opening slide says he's going to cover HttpUnit, Canoo WebTest and JMeter. I'm most interested in the JMeter stuff as I've been meaning to integrate it into AppFuse. I've used HttpUnit and it's a little verbose for me. I prefer using Canoo WebTest or jWebUnit over HttpUnit. On my current project, we're considering using jWebUnit or HttpUnit to act as a browser when interacting with a 3rd-party system.

All of these tools run functional tests - which are much different from unit tests. Unit tests usually tests the bricks, whereas functional tests test the building. For unit and functional tests to be truly effective, they must be:

  • Scriptable
  • Repeatable
  • Automated
  • Darn close to 100% coverage

The tools Scott is talking about tonight have passed his basic tests:

  • Can I learn it in 10 minutes?
  • Does it play nicely with my existing test environment?
  • Does it play nicely with my existing production environment?

I didn't take any notes about HttpUnit or Canoo WebTest because I didn't really learn anything new. Scott did do a nice job in his HttpUnit examples - he made it look a lot simpler than I've previously seen. I've used it HttpUnit before and it seems a bit verbose. I've always used jWebUnit, which simplifies HttpUnit's API.

JMeter allows you to do the same thing as HttpUnit and Canoo WebTest. It's a standalone GUI, for the complete non-programmer. It does not plug into Ant/JUnit and is mostly used for load testing. I thought it was exclusively used for load testing - and I think it has an Ant task. I could be wrong.

<sidenote>Scott uses Smultron for XML editing on his Mac.</sidenote>

The basic building block of JMeter is a "Thread Group". The Thread Group allows you to control the number of users/threads that run a particular test. You can test gets, posts, change the protocol and even upload files. For load testing, make sure and check "Retrieve all Embedded objects in HTML files". You have to view the "result windows" to view that your tests actually ran - there's no "green bar" feature.

I think JMeter has improved a lot since I last looked at it. Scott's overview and demonstration make it look very straight forward and easy to use. One guy asked if it's possible to see a a global view of all tests run. Scott thinks it's possible by adding a Listener to the Thread Group and creating a graph (one of the options). Scott is now showing a lot of the options in JMeter - there's a ton! It's almost overwhelming.

Next up is "Exceptional" Web Apps by Stephen A. Stelting, a senior Instructor and Author from Sun. His latest book is "Robust Java". Stephen has spent the last year and 1/2 figuring out how to make Java fail.

Objectives:

  • Describe the types of errors that occur in the web
  • Explain how exceptions and errors can be handled
  • Describe the web container response to exceptions
  • Present best practices to address web tier exceptions
  • Show how web frameworks handle exceptions

Payoff: As a result of this talk, you'll have a better understanding of how to use exceptions in Servlets and JSPs, improving the robustness of your webapps.

I'm a little skeptical at this point. I think most folks don't do exception handling in their webapps. I hope Stephen has some good tips and tricks for those of us who are familiar with handling exceptions. I wonder how he feels about Spring and its runtime exceptions?

There are two types of exceptions in the web tier: HTTP Errors and Java Exceptions. Standard HTTP Errors are handled by the web server. You can also send your own HTTP errors by calling HttpServletResponse.sendError(). If you're using response.sendError(), make sure and call it before you commit the output. The web.xml file allows you to specify errors and exceptions with the <error-page> element.

Servlets and Filters have similar exception behavior. Both declare exceptions in both of their lifecycle methods: init and service (doFilter for Filters). Developers throw exceptions in lifecycle methods to "tell" the container about problems.

  • javax.servlet.ServletException
  • javax.servlet.UnavailableException
  • java.io.IOException

Stephen is now describing the init() method and the exceptions it can throw. Yawn. I think most Java web developers use frameworks these days. Because of this, most developers probably don't use these methods because they don't write plain ol' servlets. One thing I didn't know is that UnavailableException takes a time parameter - if you throw an UnavailableException with this parameter, the container will retry after the specified amount of time.

Result of Exceptions in init(): The destroy() method is never called, since the initialization did not complete. Client calls during component unavailability render a 500 error.

I stopped taking notes at this point because my laptop battery was dying. I didn't really learn much in the rest of the presentation. While I can appreciate Stephen's enthusiasm, it was obvious that he was an instructor and not an in-the-trenches developer. He explained a lot of what and didn't have any code to show how to do stuff. There wasn't a single demo in the entire presentation.

Most of the exception handling stuff Stephen talked about for the rest of the session was common sense (IMO). It also centered around the Servlet and JSP API, which most folks probably don't mess with. The Struts and JSF coverage at the end was cool. If nothing else, it was to nice to hear a Sun employee confirm that JSF is quite deficient in its hooks to allow easy framework-configurable exception handling.

Now that I'm working at home, and working/interacting with friends all day - it seems that the DJUG meetings aren't as exciting. They used to be fun because I could get out of the house and have a few beers with friends. Maybe it was the lack of learning anything new tonight.

Posted in Java at Jan 12 2005, 11:30:50 PM MST 3 Comments

CruiseControl and Maven

At work today, I put together a config.xml for CruiseControl to run continuous integration builds for our project. We're using Maven, so I used the CruiseControl Plugin to generate a cruisecontrol.xml file to get started. Then I moved this file up a few directories, renamed it to config.xml and changed all the log paths to be outside of the project.

There's quite a difference between running CruiseControl with Ant vs. Maven. With Ant - you tend to delete the whole project, check it out from CVS and build/test it from scratch. With Maven, the recommendation seems to be a bit different. What I found on the mailing lists and such was that you should manually checkout your project into your "checkout" directory and then call "scm:update-project|clean test" from config.xml. With Maven, it seems there's no CruiseControl-specific maven.xml file for your project.

I tend to like the delete/checkout/test approach you get with Ant over the update/test approach with Maven. For those of you that are using CruiseControl with Maven - is it possible to do delete/checkout/test - or am I stuck with the update/test approach?

Posted in Java at Jan 10 2005, 10:34:09 PM MST 3 Comments

Setting up CVS, AppFuse, JSPWiki, Tomcat, MySQL, Apache and Bugzilla on Suse 9.2

I have a few different clients right now. One of them has taked me with building a Linux box for them, configured with all the standard stuff you need for developing/testing Java apps. I decided to document the process in hopes that the next time I do it, it will be a little less painful. The box had Suse 9.2 Professional installed on it, and was unlike most Linux boxes I've setup. There was hardly anything setup on it, not even gcc - which is used to compile/install most Linux-based software. All of the this work was done remotely, using SSH and Cygwin.

NOTE: This was written after-the-fact, so it might not be up to date. I've tried to remember what I could.

Table of Contents

  • [1] Installing CVS
  • [2] Installing Tomcat, Ant and MySQL
  • [3] Testing installation with Equinox and AppFuse
  • [4] Installing JSPWiki
  • [5] Installing Apache
  • [6] Configuring the Apache Tomcat Connector
  • [7] Installing Bugzilla

Installing CVS [#1]

When I first logged into this machine, it had virtually nothing installed. In most cases, when I've installed packages on Linux, I've found it easiest to download the source, run ./configure, make and make install because installing RPMs often gets into strange dependencies that I can never figure out. Luckily, with CVS, I was able to easily install an RPM. I uploaded the RPM for CVS from my Suse 9.2 Professional CD. I then logged in as root and installed it using "rpm -i cvs-1.11.14-20.i586.rpm".

I also setup CVSSpam, which can be configured to send us e-mails when someone commits. If you read the CVSSpam manual, you'll see that you can checkout the CVSROOT module and configure settings in there.

Installing Tomcat, Ant and MySQL [#2]

Before installing Tomcat and Ant, I had to install the JDK. There was already a JDK installed, but it was IBM's and I've had more success with Sun's. I downloaded the "self-installing binary" (v. 1.4.2_06) from http://java.sun.com/j2se/1.4.2/download.html and installed it in the /usr/java directory. I then created a jdk-1.4.2 symlink to the "j2sdk1.4.2_06" directory in this same directory. Next, I changed the Java-related environment variables in /etc/profile.d/alljava.sh to point to /usr/java/jdk1.4.2.

Installing Tomcat and Ant was fairly easily. I just downloaded the binaries and unzipped them into the following directories.

I then created "ant" and "tomcat" symlinks in the /opt/tools directory to point to these installation. Next, I created environment variables for ANT_HOME and CATALINA_HOME by appending the following to the bottom of the /etc/profile file:

#
# Java Development Enviroment Variables
#
export TOOLS_HOME=/opt/tools
export ANT_HOME=$TOOLS_HOME/ant
export CATALINA_HOME=$TOOLS_HOME/tomcat
export PATH=$ANT_HOME/bin:$CATALINA_HOME/bin:$PATH

For MySQL, I installed version 4.1.7 using an RPM. I created /etc/my.cnf file with the following settings - so AppFuse/UTF-8 would work, as well as Transactions:

[mysqld]
default-table-type=innodb
default-character-set=utf8

Testing installation with Equinox and AppFuse [#3]

After installing Ant, Tomcat and MySQL, I was able to successfully checkout Equinox (and AppFuse) into my home directory and run all tests against Tomcat.

One thing I did have to change in the default AppFuse setup was the MySQL Driver. Suse uses IPv6, which doesn't work with the current JDBC Driver in AppFuse 1.7 (or prior). You can get the latest one at http://dev.mysql.com.

Installing JSPWiki [#4]

Installing and configuring JSPWiki was fairly easy. I downloaded version 2.1.115-alpha, extracted its contents and renamed JSPWiki.war to wiki.war. Then I copied it to $CATALINA_HOME/webapps. After Tomcat expanded it, I modified the $CATALINA_HOME/webapps/wiki/WEB-INF/jspwiki.properties file and changed a few settings:

jspwiki.fileSystemProvider.pageDir = /opt/tools/tomcat/webapps/wiki/data
jspwiki.basicAttachmentProvider.storageDir = /opt/tools/tomcat/webapps/wiki/data/files
jspwiki.translatorReader.allowHTML = true
jspwiki.templateDir = blueman

I have a custom template that I use for most clients. It's called "blueman" and I downloaded it and extracted it into the $CATALINA_HOME/webapps/wiki/templates directory. I also copied the sample pages that come with JSPWiki into the /opt/tools/tomcat/webapps/wiki/data directory.

NOTE: One issue I had while doing this was having trailing spaces for the "*Dir" attributes in jspwiki.properties. Make sure these values don't have any trailing spaces.

Installing Apache [#5]

Installing Apache was the hardest part of this whole setup. Not because the installation was hard, but figuring out how to do it was. There are no pre-built binaries for Apache. I tried to install RPMs, but dependency failures kept happening and I couldn't get them resolved. I couldn't compile from source because there was no C-compiler installed. After much googling and a lot of research, I discovered I could change where YaST looked for its installation files. The default was set to look on the CDs.

To change the location, I typed "yast2", selected Software >> Change Source of Installation, and added a new FTP Source with the following settings:

Protocol: FTP
Server Name: ftp.suse.com
Directory on Server: pub/suse/i386/9.1 (I tried 9.2, but it didn't resolve)
Authentication: anonymous

I then turned off the other 2 CD sources. When I first did this, I used "yast" rather than "yast2" and it didn't seem to have any effect. In fact, I think I rebooted before I even tried "yast2", but then I read about it on some website, tried "yast2" and found I could easily install a number of programs using this utility.

After configuring the new source, I went to Software >> Installed and Remove Software and searched for "apache2". I selected the following modules to install:

  • apache2
  • apache2-jakarta-tomcat-connectors
  • apache2-mod_perl
  • apache2-prefork
  • apache2-worker

The last 2 are required by apache2. After installing all of these, Apache 2.0.49 was installed and I received a page when I navigated to the host's IP address. It turned out to be an error page, but only because there was no index.html file in /srv/www/htdocs. I created a symlink from htdocs/index.html to $CATALINA_HOME/webapps/ROOT/index.jsp (a simple static page) to solve this issue.

Configuring the Apache Tomcat Connector [#6]

I found most of the information for this section from reading the /usr/share/doc/packages/apache2-jakarta-tomcat-connectors/README.SuSE file. I've used both mod_jk and mod_jk2 in the past, but since this file said "The module JK2 is only experimental in this package", I opted to configure the mod_jk connector. Below are the steps I went through to configure Apache2 to connect to Tomcat 5.0.30 on Suse 9.2:

1. Create a file named jk.conf in the /etc/apache2/conf.d directory with the contents below. This file contains the URI mappings to tell Apache what URLs to direct to Tomcat. Many of the samples I found go a bit further and map the full directories in Tomcat, but since the apps deployed are entirely self-contained, it seems to make more sense to just do the JkMount.

<IfModule mod_jk.c>

    JkWorkersFile /etc/apache2/workers.properties
    JkLogFile /opt/tools/tomcat/logs/mod_jk.log

    # Log level to be used by mod_jk
    JkLogLevel error

    # AppFuse - the 2nd line eliminates the need for a
    # trailing slash on the URL
    JkMount /appfuse/* ajp13
    JkMount /appfuse ajp13

    # Equinox - the 2nd line eliminates the need for a
    # trailing slash on the URL
    JkMount /equinox/* ajp13
    JkMount /equinox ajp13

    # JSPWiki - the 2nd line eliminates the need for a
    # trailing slash on the URL
    JkMount /wiki/* ajp13
    JkMount /wiki ajp13

</IfModule>

After configuring Apache+Tomcat, I blocked port 8080 on the firewall and changed AppFuse to use port 80 as its default port. This is easy to do - just create a .build.properties file in your home directory with the following contents:

http.port=80

Then run "ant clean deploy". This will affect all of your AppFuse-based projects.

2. Create an /etc/apache2/workers.properties file with the following contents:

#
# You should configure your environment slash... ps=\ on NT and / on UNIX
# and maybe something different elsewhere.
#
ps=/

#
# The workers that your plugins should create and work with
#
# Add 'inprocess' if you want JNI connector
worker.list=ajp13

#------ DEFAULT ajp13 WORKER DEFINITION ------------------------------
#---------------------------------------------------------------------
#

#
# Defining a worker named ajp13 and of type ajp13

# Note that the name and the type do not have to match.
#
worker.ajp13.port=8009
worker.ajp13.host=localhost
worker.ajp13.type=ajp13
#
# Specifies the load balance factor when used with
# a load balancing worker.
# Note:
#  ----> lbfactor must be > 0
#  ----> Low lbfactor means less work done by the worker.
worker.ajp13.lbfactor=1

#
# Specify the size of the open connection cache.
#worker.ajp13.cachesize

3. Add the module "jk" to the list of apache2 modules APACHE_MODULES. It can be done by YaST in the "Editor for /etc/sysconfig Files" or by editing the file /etc/sysconfig/apache2. If you have done it by editing the file. The apache2 configuration has to be updated by the command:

SuSEconfig --module apache2 

4. Make sure the server tomcat is stopped.

5. Change CATALINA_BASE to "/opt/tools/tomcat". It can be done by YaST in the "Editor for /etc/sysconfig Files" or by editing the file /etc/sysconfig/j2ee. (I don't think this is necessary since I didn't install Tomcat using YaST).

6. Start Tomcat and restart Apache using "rcapache2 restart".

Installing Bugzilla [#7]

To install Bugzilla, I downloaded the 2.18rc3 version and extracted it to the /opt/tools directory. I then moved it to /opt/tools/bugzilla and cd'd into it. Then I ran "./checkconfig.pl" and proceeded to install the Perl modules it told me to. Then I modified the "localconfig" file in this directory. I changed the "$webservergroup" to be "" since I couldn't figure out what group Apache's files were supposed to belong too. I also changed the "$db_user" to be "root" since I couldn't get the "bugs" user to work. The group and db_user are things that I still need to fix - any advice is appreciated. I changed the "$webservergroup" to be "www" (thanks John Norman) and I had to use old_password() on the "bugs" user to get bugzilla to work with MySQL 4.1.7.

Next, I edited the /etc/apache2/default-server.conf file so "/bugzilla" would be recognized. I added the following right after the configuration for the "/icons" directory.

Alias /bugzilla "/opt/tools/bugzilla"
<Directory "/opt/tools/bugzilla">
        Options FollowSymLinks Indexes Includes +ExecCGI
        AllowOverride All
        DirectoryIndex index.cgi
        Order allow,deny

        Allow from all
</Directory>

Then, at the bottom of the file, I added:

AddHandler cgi-script .cgi

I restarted Apache and I kept getting an error that Apache couldn't open the /opt/tools/bugzilla/.htaccess file. I tried running "chmod +r", "chmod 644", "chmod 755" and even "chmod 777", but no luck. Finally, I googled and found that running "chmod 701 /opt/tools/bugzilla" solved the problem.

Hopefully this will help anyone else trying to setup these tools on a remote Suse box.

Posted in Java at Jan 04 2005, 03:58:03 PM MST 11 Comments

RE: J2EE App Server Security

Dion and Christian are talking about J2EE App Server Security. Specifically, they are talking about setting up standard container-managed security. J2EE allows you to specify security settings in your web.xml, but to make those work - you have to configure your app server. For Tomcat, this is pretty easy, and Resin makes it easy too. However, the XML you have to write for both is quite different and some app servers don't even let you write XML - instead you have to use their "admin console". Personally, I think most admin consoles are a pain in the ass. I'd prefer to write a single XML file to configure the server. Some servers require several files just to authenticate against a database.

AppFuse uses both container-managed authentication and a JNDI DataSource. This means you have to configure the appserver in order to run AppFuse. On many servers, this is difficult to do (or, they didn't pass my 10 minute test at least). I like servers where I can deploy a couple of JARs into a directory and a single XML file to configure the server. Tomcat and Resin come to mind.

After using Acegi for the last month, I think I'm going to ditch the "standard" J2EE security stuff. I managed to port AppFuse to use Acegi last month - and didn't have to change a single line of security-related code. The hardest parts of integrating Acegi where 1) figuring out how to build it from CVS (there's currently two src trees) and 2) excluding URLs. Once I got these two things solved, I had to add an "enabled" column to my user table, but that's about it. This is awesome b/c it means you can always port back to CMA with very few code changes.

I used to think that using the container's resources was a good thing, but I'm starting to change my mind. Spring allows you to configure a DataSource connection pool just like Tomcat does, so there's not as many benefits as there once was. Being able to drop a WAR into a directory and have your app work without configuring the server is a very nice thing. What do you think? Are there any advantages to using a container's services anymore? I suppose there is for distributed or clustered apps, but that's all I can think of.

Posted in Java at Jan 04 2005, 09:59:26 AM MST 17 Comments

If you could add another framework to AppFuse, which would it be?

If you could add another web framework option to AppFuse, which one would it be and why? Please keep in mind it already includes Struts, Spring, WebWork, JSF and Tapestry.

Posted in Java at Dec 13 2004, 09:52:17 PM MST 38 Comments

AppFuse Tip: Backup and Restore Data with DbUnit

One of the nice things about having DbUnit integrated into AppFuse is you can easily import and export data. I've often used this feature to export a test database (or even production) into my development environment to try and reproduce data-related errors. Here's how to do it:

  1. Run "ant db-export -Ddatabase.host=otherhost". This exports all the data into an XML file named "db-export.xml" in the current directory.
  2. Run "ant db-load -Dfile=db-export.xml" to import the data into your local database.

I've used the db-export task for other things too - like populating the database through the UI and then updating the test data. All you have to do for this is to copy the db-export.xml file to metadata/sql/sample-data.xml.

NOTES:

  • For Oracle, you need to add a "schema" attribute to all the <dbunit> tasks in build.xml. You also need to do this for the "db-export" target for PostgreSQL.
  • If you want to limit the tables exported (i.e. from a production database), simply nest a bunch of <table name="table_name"/> elements inside the <export> element.
  • If you get errors about foreign key constraints when running "db-load" after "db-export" - you need to re-arrange the order of your tables in the imported XML file.
  • To clear out tables before your tests, add an empty <table name="table_name"/> element to sample-data.xml.

Posted in Java at Dec 13 2004, 10:43:18 AM MST 2 Comments

How do I attach a profiler to Ant?

I'll admit, I have very little experience working with a profiler - but I think I need one. Someone e-mailed me about testing all of AppFuse on a super-beafy box, and he got OOM errors after 17 minutes. For a dual CPU, 2Ghz Opterons, with 2GB RAM running RHEL3 workstation, it only made it to the Spring/AppGen test, which is #8 of 21. On my PowerBook, it makes it to #12, but my Linux box only make it to #8 too. My guess is there's some sort of memory leak in one of the testing tools - Tomcat, Cargo, WebTest or AppFuse itself.

Anyone have experience attaching a profiler to their Ant build or testing process to look for memory leaks?

Posted in Java at Dec 12 2004, 10:55:35 AM MST 10 Comments

Can you test all of AppFuse?

I'll admit, it's time for me to get a G5. I can no longer test everything in AppFuse in one fell swoop. When I try to run this Ant build file(info) (which I'd like to use with CruiseControl) on my Mac and Linux machines, I get OutOfMemory errors. My PowerBook has ANT_OPTS set to "-Xmx768m" and my Fedora Core 3 box has it set to "-Xms1024M -Xmx1024M". Both machines have 1 GB of RAM. The build dies a lot sooner on Linux (15 minutes), and the PowerBook gets really close to finishing (42 minutes). I'm guessing all the tests would take about 50 minutes on the PowerBook. There are currently 21 AppFuse combinations tested by this script. Spring is used in all of these, so I've eliminated that as a listed option.

NOTE: If you're trying this on Windows, remove the "fixcrlf" call at the beginning of the "test" target.

  1. Struts + Hibernate
  2. Struts + Hibernate and iBATIS
  3. Struts + iBATIS
  4. Struts with AppGen - Generic
  5. Struts with AppGen - Detailed
  6. Spring MVC + Hibernate
  7. Spring MVC + iBATIS
  8. Spring MVC with AppGen - Generic
  9. Spring MVC with AppGen - Detailed
  10. WebWork + Hibernate
  11. WebWork + iBATIS
  12. WebWork with AppGen - Generic
  13. WebWork with AppGen - Detailed
  14. JSF + Hibernate
  15. JSF + iBATIS
  16. JSF with AppGen - Generic
  17. JSF with AppGen - Detailed
  18. Tapestry + Hibernate
  19. Tapestry + iBATIS
  20. Tapestry with AppGen - Generic
  21. Tapestry with AppGen - Detailed

So, the question is - can your machine run all the tests for AppFuse? If so, let me know your specs. I'd love to get this setup for CruiseControl, but if I can't even run it with Ant, I doubt CruiseControl will be any better. I realize I could split things up, but I prefer to have one build file.

Posted in Java at Dec 10 2004, 08:51:02 AM MST 8 Comments

[ANN] AppFuse 1.7 Released

This release adds support for JSF/MyFaces and Tapestry as web framework options. AppGen has been updated to work with both of these frameworks and I added new tutorials as well. You can read about my integration experience in a previous post.

After I released AppFuse 1.6.1, I knew the only way I was going to get Tapestry and JSF support done was if I stayed close to the code and started the next release. I never envisioned developing the Tapestry and JSF versions of AppFuse at the same time, but it turned out to be very efficient. If you want a comparison of all the different web frameworks in AppFuse (and AppFuse Light) - you can checkout my Comparing Web Frameworks presentation. If you want more in-depth coverage - it'll be in the next Chapter of Spring Live. ;-)

If you find any issues, let us know.

Posted in Java at Dec 08 2004, 11:30:25 AM MST 9 Comments