Matt RaibleMatt Raible is a Web Developer and Java Champion. 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.

Time to learn more about Podcasts

Now that I'm commuting to work everyday, I have 15 minutes each way on the Light Rail to read, listen to music or whatnot. I've been reading Tapestry in Action, but I think I'd like to get into Podcasts. I know a little bit about them, but not a whole lot. In the ideal world, I could subscribe to a podcast's feed in iTunes and everytime I'd synch my iPod - it would grab the latest podcast for a particular site. However, doesn't seem to be the case. As far as I can tell, I have to subscribe to someone's site with a podcast, then manually click on their "mp3" link - and then synch it to my iPod.

Is that how podcasting works? If so, it seems like there's a lot of user effort required. I suppose I can do the manual click-n-listen at work, but I'd prefer a more automated solution for the commute.

P.S. The bagel shop downtown (16th and Cali) has free wi-fi - sweet!

Later: I'm over it. I tried listening to a podcast while writing for the last 20 minutes. It's boring compared to music. I guess I'm not geeky enough.

Posted in The Web at Jan 11 2005, 06:40:51 AM MST 9 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

New Gig starts Monday

It's official - I'll be starting a new gig on Monday. I'll be working on a project at Xcel Energy in downtown Denver. I've always wanted to work downtown - so I'm pretty pumped about it. I had internships there in college, but never worked there in the "Real World". I signed a contract through the end of the year, but it sounds like they have a lot of work, so it could be longer. The best part is I'll be working with Bob Johnson and Bruce Snyder - both good friends of mine.

I met Bob while working on a contract in 2003. We didn't work on the same team, but he was the first AppFuse user I'd ever met. I'll also be working with Jeff Genender, who supposedly has the Tomcat integration done for Geronimo.

I'm definitely looking forward to working on a team again, especially with these guys. I'm thinking of riding my bike to work everyday, but that might have to wait until March. I was going to try and raise money for the tsunami victims by riding no matter what (snow, cold or rain), but I don't know if anyone would donate. It should be an easy 20-30 minute ride when the weather gets nice.

Posted in General at Jan 07 2005, 05:18:02 PM MST 6 Comments

Using Acegi Security with AppFuse

Want to use Acegi Security in your AppFuse project? Here's how. Acegi Security will replace Container-Managed Authentication in the next release of AppFuse (1.8). All the code for this was added to CVS today.

Posted in Java at Jan 07 2005, 02:57:49 PM MST 12 Comments

Java and Booze next Monday in Denver

Fellow Roller developer Lance is coming into Denver for a brief business trip next week. We're going to hook up for some dinner and drinks at CB Potts on Monday night at 6. If you want to talk about Roller, Java or authoring books - please join us. The more the merrier!

Posted in Java at Jan 06 2005, 11:24:26 AM MST 2 Comments

How do you become an independent consultant and get contracts?

A friend recently sent me an e-mail looking for advice on becoming an independent consultant and specifically how to get contracts. I thought this advice might be interesting for others. The e-mail below is unmodified for the most part. He's an animator and does a lot of stuff in Flash, so this naturally has that twist to it. For Java Developers, just replace Macromedia/Flash stuff with Java stuff.

The best thing is to subcribe to the job mailing lists in Denver. There's a Rocky Mountain Internet Users Group and Macromedia Users group that would probably help you.

http://www.rmiug.org/html/email_lists.html

http://www.rm3ug.com

Then I would advise you to get involved in with a local user group, like the Macromedia one. Attend meetings, talk to people, see where they're getting their gigs. I go to the Denver Java Users Group on a monthly basis and now I have a lot of friends there. It was nerdy at first, but then I realized they all went out for beers afterwards and it's kinda cool now. If you volunteer to speak at one of the meetings, you'll probably get some leads from that. It's really all about networking.

The best thing you could possibly do for you career and new clients is to start a weblog. On it you can talk about what you do and how you solve problems. Tips and tricks kinda stuff. I put a lot of personal stuff on mine (www.raibledesigns.com) too. Ever since I started my weblog, I haven't had to do much looking. Often, I can just post I'm looking for a new gig and I'll get offers. I get 8000 visitors a day and around 2 million hits a month. It's the main reason I got my last couple of book deals.

Any other advice you might have for people looking to become independent consultants?

In general, I find independent consulting a lot more fun than full-time employment. The main benefits of full-time employment are Health Insurance and 401K Plans. Stock options are not a benefit in my eyes. I've yet to meet anyone who has made money off stock options as a full-time employee.

The main benefits of being an independent consultant are higher pay and freedom. An experience full-time Java Developer (in Denver) makes around $100K year. I've heard of companies hiring employees for $120K, but the most I've known anyone to make is $108K. On other hand, a contractor with only a year or two of experience can easily make $55/hour - or $110K year. Experienced developers get anywhere from $75/hour to $200/hour. That's right folks - $150K year to $400K year! For the higher dollars you often have to travel, which kinda sucks.

People that are full-time employees often like it for the benefits - health care and such. As a consultant, you get to see how screwed up our health care system is and pay for your health insurance out-of-pocket. I've seen folks pay anywhere from $250/month to $1000/month for health insurance. We've done both (the latter thanks to Corba) and I'm happy to say that we're paying $250/month now. United Healthcare, minimal plan - but we're still insured. What about 401K? As an independent, you often will establish your own company, and then you can contribute to an SEP plan. With a 401K, you're limited to contributing something like $15K/year. With an SEP, you can contribute up to $40K! Granted, you won't have any employer matching, but you can still plan for your retirement.

The one downside I've seen personally from being independent is I tend to find a lot of projects where I'm the development team. This is great at first since I can work remotely and don't have to attend any meetings, but I tend to miss the water-cooler talk and synergy that a team provides. With full-time positions, this can happen too, but it's rare. With full-time positions, you're likely part of a development team - and if you're lucky - one full of smart developers. One myth about contractors is that they often don't fit into a team full of full-time employees. Personally, I've found this to be a personality thing and have rarely had issues fitting in with full-time employees. The ideal situation is simply to work with smart people. In my career, working with people smarter than me has always been very lucrative to my knowledge base.

Working from home is not all it's cracked up to be. I've done it off and on for a few years now and I'd much rather go into an office at this point. When I work from home, dinner tends to be a just a "break" in my day and I go back to work after the kids go to bed. When I'm in an office, the work day ends when you leave. So how do you get the team-benefits as a independent consultant? The best way I've found is to work with a group of consultants on a project - where the whole team is contractors. You'll often share the same lifestyle and attitudes about your careers. Also, a lot of independent consultants tend to be smart - so you get that benefit.

The last thing I like about independent consulting is freedom. I had 4 months last year where I attended conferences, went on vacation or worked on Spring Live. Good luck finding that kind of freedom with a full-time gig. The higher rates allow you to take more time off to spend with your family - or just enjoy life in general.

If you're thinking about becoming an independent consultant, now is a better time than ever - especially if you live in Denver. The Denver JUG mailing list received more job postings last year than any previous year. From what I've seen, at least half of these are for contracting positions. Unfortunately, most of them are in the $40-60/hour range, but that's still good money.

Any feedback on why you think being a full-time employee is better is most welcome.

Posted in Java at Jan 05 2005, 04:45:14 PM MST 25 Comments

Macworld Expo

Erik expects an AirPod to be announced at the Macworld Expo next week. While that would be cool, I'm hoping for a dual processor 2GHz PowerBook. Jeff mentioned this might happen sometime this Spring. I'd rather have a G5, but I'll settle for a 2GHz G4.

Posted in Mac OS X at Jan 05 2005, 11:57:33 AM MST 2 Comments

It figures...

Today is the first day I've had to go into an office since May of 2004. Today should be a 9" day here at Raible Designs - there's 12" of fresh powder at Vail. However, I managed to get a 3-day architecture-review contract so I'm heading to the client's site downtown. To enhance the commuting experience, it's colder than a witch's tit outside (2°F) and there's a few inches of fresh snow. I think I'll try the Light Rail (there's a station 1 mile from our house) and hope it's not too crowded.

Posted in General at Jan 05 2005, 07:27:02 AM 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