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 "struts". 659 entries found.

You can also try this same search on Google.

Want to use Struts with EJBs?

If you're looking to use EJBs in your Struts project - you might want to take a look at StrutsEJB on java.net. I have no opinion on this project, just thought I'd provide a little visibility.

Posted in Java at Jan 30 2004, 08:27:34 AM MST 2 Comments

Tapestry vs. Struts

I've been watching the Tapestry mailing lists in hopes of picking up some tips before I start learning it. In reality, I'm waiting for Tapestry in Action, which will hopefully make it easier to learn. Today, there was a very interesting thread comparing Tapestry to Struts. It looks to me that Tapestry is easier to develop with once you get the hang of it, but apparently, it has a steep learning curve.

The Tapestry Mailing list is interesting - it seems to have a different level of users. Maybe it's just me, but they seem to be a more enlightened crowd. You could almost say the same for the WebWork mailing lists. If I compare these two lists to the questions on the Struts mailing lists - it seems like there's a bunch of idiots over there (on Struts). Don't these people know how to use Google?! To be fair to Struts, I have a theory.

If WebWork or Tapestry ever becomes as popular as Struts, they'll get their fare share of idiots too.

It's just the nature of mailing lists - it's so much easier to ask your question than to look for the answer. Which reminds me...

Don't ask dumb questions...

Posted in Java at Jan 28 2004, 09:51:15 PM MST 2 Comments

[Review] Java Open Source Programming

Book Cover Today I finished reading Java Open Source Programming. It took me one week to read - and I only read about an hour a day. This book is nice to read - you can breeze through 20 pages in no time. I appreciate a quick-read technical book. I enjoyed the simplicity of this book, especially since I'm such a rookie at WebWork, SiteMesh and Mock Objects. I knew most of the Hibernate and XDoclet stuff, but I did manage to pick up a few tricks, and since it's the only book on Hibernate (that I know of), I'll refer to it when I need to do components or proxies. Overall, this book made WebWork and SiteMesh look like great technologies and I'm excited to start using them.

The sample app, PetSoar, continues the "call your persistence layer from your action class" that I've seen in all WebWork sample apps. I still don't know if this is a good idea, but since Actions aren't tied to the web, maybe it is. This means you put your business logic in your controllers (a.k.a. actions). Kinda breaks the whole controllers should only be controllers mantra, but whatever floats your boat. To be honest, in AppFuse, all the Managers (a.k.a. business layer) do is transfer POJOs to ActionForms, and then back again. The Managers are were my business logic should go, but I often find it easier to put it in my actions. I sense a paradigm shift - will the WebWork version of AppFuse only contain a "dao" layer and a "web" layer? Who knows - only time will tell.

One interesting thing I picked up is the different way that Dependency Injection (a.k.a. Inversion of Control) is handled in WebWork compared to how its handled in Spring. In Spring, all you need to do is add a setter (and local variable) to prepare a class for IoC. When using WebWork, you have to create an Interface that has the setter defined, and then your Action must implement that interface. If Spring can do it without an interface, why can't WebWork?

All in all, I enjoyed this book - though it didn't peak my interest as much as J2EE Design and Development. I think that's probably because Spring solves some issues I've had with AppFuse (binding interfaces and implementations), whereas this book doesn't really solve anything for me. As a WebWork newbie though, I do feel this is a good read. I also found myself saying "Wow, that's cool" a fair amount of times (re: SiteMesh and WebWork).

I was disappointed that i18n was not covered at all. I tend to always prepare my Struts apps for i18n (extracting text into a .properties file). However, in most cases, a 2nd translation has never been put in place. So, I bitch about the lack of i18n coverage, and I write my apps with i18n in mind, but it's never been used in any of the apps I've written. Maybe I should just quit doing i18n in my apps - it'd probably save an hour a week of development time.

So it comes down to this - if you don't know anything about WebWork, this book is a worthwhile read. If you know WebWork - I'm sure you'll be disappointed because it is written for newbies.

Next up, upgrading my programmer certification to 1.4 with the Sun Certified Programmer & Developer for Java 2 Study Guide.

Posted in Java at Jan 25 2004, 01:29:19 PM MST 7 Comments

Anyone else having trouble with SourceForge's CVS?

SourceForge's CVS repositories have been acting up since yesterday - at least for me. I just did a clean checkout of AppFuse and I got version 1.0. WTF? Even ViewCVS shows that my latest code is there. Wierd.

Posted in Java at Jan 23 2004, 10:32:16 AM MST 2 Comments

A few thoughts on AppFuse

I've been thinking about how to structure AppFuse for the upcoming Spring and iBatis enhancements. These enhancements shouldn't require any directory structure changes. However, I've received some suggestions to change the common, ejb and web directory structure to be a little more inline with the tiers. So it would become something more like database, business and web (or dao, service and web). After thinking about this for the last couple of days, it seems to make sense. I picked up the notion of common from Erik Hatcher's JavaDevWithAnt, which I borrowed heavily from when creating AppFuse. Erik used common because this represented classes that would be included in both the web tier and the EJB tier. But since I (currently) don't plan on every adding EJBs to AppFuse, does it make sense? Even if I did, I'd probably only use SessionBeans, and those could easily fit into the service layer. The nice thing about moving the business layer (currently in web/**/services) to it's own directory is that it will get it's own JAR (with hardly any modifications to build.xml) and can be used outside of the webapp.

The nice thing about isolating the web directory to web-only classes is I can use Ant to replace any Struts-specific classes with WebWork or Tapestry. To prevent AppFuse from being cluttered with too many options, it'll ship with Struts out-of-the-box. If users want WebWork for their framework, they can download a WebWork version of the web-tier and run an Ant target that will replace all the Struts stuff with WebWorks stuff. It seems like the cleanest way to do web framework switching.

Another thing that might happen to AppFuse, caused by my enthusiasm to try out everything, is that it will contain too much stuff for a basic web application. It currently has security and user management built in, which is what most webapps need. I recently added in OSCache and Clickstream. OSCache is not enabled, but most webapps can probably use it somewhere. Clickstream is a different story. For most of the webapps I've built, this is not needed at all. Most of the apps are no more than 20 screens, and it's unlikely the client will care where people go the most. Another option that deserves ripping out is the idea of Struts' submodules. I tend to rip this out as the first thing when starting a new project. File Upload is something I've used rarely, so I should probably lose that feature too.

There are also other technologies that I've thought of adding to AppFuse, namely Quartz and Lucene. However, I've only used Quartz on 1 of my last 5 projects and Lucene on 2 - so obviously these might be considered bloat for a basic webapp. I think the best thing would be to implement these in AppFuse, on my own, and then document how I did it on the wiki (for an example, see diagramming build.xml with Vizant). If folks need to use it they can add it on their own. Documentation is always good, and if I can just document how to add stuff, I can certainly reduce the bloat.

Whaddya think - is it better to include options out-of-the-box or simply document them? Should I restructure the directories to match the tiers more?

Posted in Java at Jan 23 2004, 06:58:11 AM MST 9 Comments

Poor Open Source Developers

Richard seems to think that most open source developers are like starving artists:

While a few make really good money selling consulting and training and other services, the vast majority of open source developers don't make anything.

For some reason, I don't believe this. The open source projects I participate in, as well as the ones I admire and use - all seem to have developers that are gainfully employed and making money. Of course, this may just be a Java open source phenomenon.

To do open source, you have to have a day job. You can't expect open source to feed your family or even your cat for that matter. As I said there are exceptions, but most open source developers do it for the love of writing software. While commercial software developers do a great job of feeding their families, open source developers do a better job of feeding their minds. In the end, you have to ask yourself which is more important: The things you own or freedoms you have.

Very good points. I dig working on AppFuse, as well as Roller, Struts Menu, and the Display Tag because I can do whatever I want. I can implement silly features like Clickstream and I don't have to ask anyone if it's a good idea (I'm still debating this).

Back to my point though. I firmly believe that most Java Open Source Developers are gainfully employed and not starving artists. Part of this comes from the fact that most of the big projects I work with (i.e. Struts and Hibernate) have some smart folks on staff, and the popularity of their projects has provided them with more opportunity, hence they're employed.

Personally, I do open source because I want to learn. I want to write code that gets scrutinized by the masses. As an independent consultant, I rarely get another person looking at my code - so I turn to the community by opening my code (that I use on a daily basis) to other developers. Overall, having others look at my code has resulted in much higher quality software for my clients, and has helped me learn a lot in the process as well.

I also look at open source development as a good marketing campaign - here's what I can do, hire me. This has proved very successful so far. Hence, my formula: Open Source Development = good marketing = gainful employment.

Posted in Java at Jan 22 2004, 06:42:57 AM MST 4 Comments

Velocity's DataSourceResourceLoader

In the current project I'm on, one of the major requirements is to have the ability to send job postings to job boards such as Monster.com, CareerBuilder.com, etc. - as well as local newspapers. When I first started this project, I went about contacting all of these advertisers and explained that we'd like to automate the process of talking to their system. I found that many of them preferred a simple e-mail with the job posting, but others wanted us to FTP a pre-formatted document to them.

I figure the easiest way to handle this is to use Velocity. By using Velocity, and storing templates in the database, users of the system can either (1) use a default template or (2) customize a template for a specific advertiser. This was all easy enough since we're using Struts Resume as a baseline for this project, and Velocity is already built-in.

I remembered seeing that Velocity had some sort of database ResourceLoader, so I went searching and found the DataSourceResourceLoader:

This loader will load resources from a DataSource such as a database. This loader is not built as part of the standard build as it requires J2EE support. To build this loader, please download the J2EE distribution, move the j2ee.jar into the build/lib directory, and then build the new velocity jar with the jar-j2ee build target. For more information on this loader, please see the javadoc for DataSourceResourceLoader.

After checking out Velocity 1.4.1 RC1 (are they ever going to release this thing?) from CVS, I was able to build a new Velocity JAR. To compile using J2EE 1.4, you have to modify the VelocityServletTest, or delete it. I then replaced velocity-1.4-rc1.jar with this new JAR (which is actually 4KB smaller), configured velocity.properties and Voila - it worked! Clean and easy integration - just the way I like it.

Posted in Java at Jan 21 2004, 06:28:50 AM MST 3 Comments

AppFuse vs. Spring

I received an interesting e-mail this morning. The writer said his team is comparing AppFuse and Spring in terms of kick starting a project. This struck me as odd, especially since these two applications are quite different. Here's my response:

I think AppFuse and Spring are two completely different animals. IMO, Spring is excellent for wiring components together (i.e. Interfaces and Implementations) as well as simplifying J2EE's APIs. Of course, it has its own web framework too, but it also integrates nicely with Struts, WebWork and Tapestry. AppFuse is designed to be an application that helps you get *up and running* with your J2EE web application in the minimal amount of time. Its power is in the directory structure, Ant integration (build.xml) and testability. Also, XDoclet is heavily leveraged for code generation and maximizing developer's productivity. In essence, it's really just a packaging of other open source projects, including: Ant, XDoclet, Hibernate, JUnit, Cactus, StrutsTestCase, Canoo's WebTest, Struts Menu, Display Tag Library, JSTL and Struts (including Validator and Tiles). But rather than just packaging these together, it's also got Security and User Management built-in and contains tutorials on how to develop and test the different layers.

Here are some links on integrating Spring with other Java-based web frameworks:

Struts: http://struts.sourceforge.net/struts-spring/
WebWork: http://wiki.opensymphony.com/space/Spring+Framework+Integration
Tapestry: http://www.springframework.org/docs/integration/tapestry.html

And here are a couple of good simple descriptions of Spring:

http://test.javaranch.com/wiki/view?SpringFramework
http://barracudamvc.org/lists/archives/barracuda/2003-December/007156.html

I do plan on integrating Spring into AppFuse in the next release - so it might be awhile until I release 1.4. I basically plan on using it to wire my Managers together, as well as my DAOs. Currently, I don't think I'll use its web framework, but who knows. In the latter half of this year, I hope to add support for WebWork and Tapestry as web frameworks.

Posted in Java at Jan 20 2004, 06:05:11 AM MST 2 Comments

Struts' MappingDispatchAction

I stumbed upon Struts' MappingDispatchAction this morning. It's basically the same thing as the LookupDispatchAction (which I use as my BaseAction in AppFuse), but you specify the method name in the action-mapping - rather than with request parameters (i.e. ?action=methodName). At first, this would seems tedious, but I usually end up creating a lot of action-mappings for a single action anyway, so this might be the way to go. There's really no need to change this in AppFuse now, but it is available in AppFuse's struts.jar (nightly from Dec 2, 2003).

In other news, the Open Source book is humming right along. I've finished the Hibernate, WebWork and Sitemesh chapters. I like what I see. IMO, this book is excellent for Hibernate, WebWork and Sitemesh newbies like me.

Posted in Java at Jan 20 2004, 05:38:43 AM MST 2 Comments

RE: AppFuse (Getting started with...)

Rick Hightower has started using AppFuse. It looks like he had a couple of issues, so I figured I'd post some solutions here for all to see (also because typing in comments w/o HTML on JRoller sucks).

Rick - I don't know why you're getting the first error with CATALINA_HOME. I just tried removing that as an environment variable on my PowerBook and I'm able to run "ant setup-db" just fine. If you've setup the MySQL database with the default settings, you should end up with a "root" user and a blank password. These settings are both specified in properties.xml, where database.admin.username=root and database.admin.username=(nothing). Of course, you can change these properties values by editing properties.xml, or by specifying them in your build.properties file. From the following error on your site:

db-load:

BUILD FAILED
C:\source\appfuse\build.xml:931: java.sql.SQLException: Invalid authorization sp
ecification,  message from server: "Access denied for user: 'rick@localhost' (Us
ing password: YES)"

It looks like you have an administrator named "rick", but that your password was incorrect. YES is not the password you provided - that's just MySQL saying that you did provide a password.

The database creation script is at metadata/sql/mysql-create.sql and it simply creates an "appfuse" database and gives a user named "test" access to it.

create database if not exists appfuse;
grant all privileges on appfuse.* to test@"%" identified by "test";
grant all privileges on appfuse.* to test@localhost identified by "test";

The next error about j2ee.jar should be self explanatory and it looks like you figured that one out. I wish I didn't have to include the entire j2ee.jar in the classpath, but XDoclet requires javax.ejb.* JARs be in the classpath for generating Struts ActionForms from POJOs.

The last thing you did - ant -Dapp.name=sampleApp -Ddb.name=database - was to merely run the "package-web" target. It's the default target in build.xml. It simply compiles everything and packages into an appfuse-1.3.war file. In this scenario, the app.name and db.name mean nothing. If you want to create a new AppFuse project, you need to specify the new target. This will create a new project.

foxxy:~/dev/appfuse mraible$ ant new -Dapp.name=test -Ddb.name=test
Buildfile: build.xml

clean:
     [echo] Cleaning build and distribution directories
   [delete] Deleting directory /Users/mraible/workspace/appfuse/build
   [delete] Deleting directory /Users/mraible/workspace/appfuse/dist
   [delete] Deleting: /Users/mraible/workspace/appfuse/database.properties

new:
     [echo] Creating new application named 'test'...
     [copy] Copying 318 files to /Users/mraible/workspace/test
     [copy] Copying 1 file to /Users/mraible/workspace/test

BUILD SUCCESSFUL
Total time: 21 seconds

I just tried this, followed by the commands specified below and all seems to be working just fine (BUILD SUCCESSFUL - Total time: 5 minutes 13 seconds).

cd ../test
ant setup-db
ant setup-tomcat
ant test-all

Just to be clear, here's a breakdown of what the above targets do:

  • setup-db: creates a database for the project, assigns users, creates all the tables and populates it with test data.
  • setup-tomcat: copies a context.xml file to $CATALINA_HOME/webapps and copies the database driver to CATALINA_HOME/common/lib.
  • test-all: runs all the tests to verify the functionality of the app. These include test-ejb for the DAO layer, test-canoo for all the JSPs and test-web for all the StrutsTestCase/Cactus tests and business layer tests (*ManagerTest).

The first steps after creating a new AppFuse project are probably to rename the packages to fit your company's naming convention - i.e. org.appfuse -> com.company.appname. In Eclipse (and propably IDEA), this is fairly easy. Just make sure to do it in the "src" and "test" directories, as well as search for it - it might be specified in a few XML files (i.e. hibernate.cfg.xml). You'll also need to modify the "javadoc" target to ensure that it looks for the write package names. Currently, it's set to "org.*".

Hope this helps!

Posted in Java at Jan 19 2004, 05:55:25 AM MST 1 Comment