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

You can also try this same search on Google.

[ANNOUNCE] StrutsTestCase v2.0 Released!

StrutsTestCase v2.0 improves support for Struts 1.1 (including better support for testing Tiles and sub-applications), provides several requested enhancements, and fixes many reported defects.

The project home page can be found here:

    http://strutstestcase.sf.net

Notes for this release can be found here:

    http://sf.net/project/shownotes.php?release_id=157811

Questions and comments are always welcome!

Deryl Seale -

I just replaced the 1.9.5 JAR with the new 2.0 JAR and all my Action tests ran lickedy-split! Now I just have to get off my duff and write some Action tests for Roller.

Posted in Java at May 07 2003, 05:27:14 PM MDT Add a Comment

Cannot load JDBC driver class 'null'

I'm going to post my newly-found solution to an often-seen error in hopes that it will help someone. In the struts-resume demo application that runs on this server, I've been getting the following error message everytime I startup the context.

java.sql.SQLException: Cannot load JDBC driver class 'null'
        at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:529)
        at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:312)

In the past, this problem has been caused by not having the JDBC driver in my $CATALINA_HOME/common/lib directory, having an invalid username/password, or having another JNDI setting incorrect in server.xml. The strange thing about the problem this time was that everything was correct, and the app ran fine, save for the error (in the log file) on startup. Tonight I figured out the solution - I needed to grant permissions for the user with the specific hostname of the machine. I've been using the following SQL to grant permissions to the app's db user. This is the syntax for MySQL, it is probably different for other databases.

grant all privileges on resume.* to username@"%" identified by "password";

While this has worked on my WinXP machine, it failed on my RH9 box tonight. The solution turned out to be specifying the specific HOSTNAME (i.e. drevil.raibledesign.home), rather than "%".

grant all privileges on resume.* to username@HOSTNAME identified by "password";

Here Google, come and get it!

Posted in Java at May 06 2003, 10:52:24 PM MDT Add a Comment

CSS Tabs and Cool Designs

I found some great stuff over at Zeldman's place this evening. First of all, I'm definitely going to bookmark this page at Webgraphics. It has a bunch of tabbed interface experiments using CSS - which will be very handy when integrating Roller's tab-based menu into struts-menu.

The second ultra-cool item of business is the very cool sites Zeldman lists in the following quote. If any of you Roller users are looking to design a new theme - I'd love to see any of these integrated into Roller.

Repeating background patterns, once the shame of web design, have recently made a tasteful comeback. (Background patterns are new grey.) If you can't design your own patterns, Squidfingers offers over 120 lovely background patterns you can use on your site. Go get 'em. If you can design your own backgrounds, K10k has launched a Pixel Pattern Exhibition and invites you to submit your designs.

Posted in The Web at May 03 2003, 10:35:37 PM MDT Add a Comment

Braindump: Roller, Hosting and Wrox

I have a lot of things I want to mention, so let's just get right to it.

Roller should bundle Moblogger
It'd be cool if Roller bundled Russ's Moblogger as part of the application. It'd be pretty easy, all we'd need to do is slap a UI on it's config file - possibly put the config into a database, and maybe even use Roller's "page" feature for the e-mail templates. Then we'd have to figure out a way to start Moblogger's thread in the background and possibly do one thread for each user.

Roller Plugins
Should Roller add a Plugins feature like Blojsom has? Why should we? If we should, maybe we should just re-use an existing plug-in API - i.e. Struts' or Blojsom's. What would make a good plugin? Is this just a fancy name for a feature that can be turned on/off (i.e. comments).

Struts Menu for the Editor
I hope to add the ability to choose different menu types in Roller's Editor UI. First, I'll have to integrate Roller's tabbed menu as a displayer for struts-menu [demo]. The CoolMenu's displayer will work great (and require less mouse clicks). I mention this in hopes of making Lance and Dave aware of any schema changes that need to be made to support a user-selectable menu type. I'll also need to add the ability to specify struts-forwards in the menu-config.xml (not implemented yet in struts-menu).

This site and my provider
This site was down a lot today - probably because of all the hits from javablogs.com (just put Hibernate in your title). I noticed that Simon and Sam's sites were down as well. This leads me to believe that my kgbinternet.com is not up to snuff. Dave and Lance seem to never have issues with Roller crashing - so why am I? Please recommend any hosting providers that offer private Tomcat instances (preferrably with lots of RAM and disk space).

What's up with Wrox and Professional JSP 2.0
Who knows... I haven't heard a thing, from anyone. Think I'd get anyone's attention if I slapped both of my chapters on this site - free of charge? I doubt it. I might just do that if I don't get any feedback in the next week or so. Are they gonna sue me for the pocket change they paid me to write the chapters?

Now I'm going to assign this to my Java category and see if all you java.bloggers can crash this site again. ;-)

Posted in Java at Apr 29 2003, 11:20:43 PM MDT 8 Comments

Hibernate Upgrade (1.2.4 to 2.0 rc1) Redux

My last upgrade from Hibernate 1.2.x to 2.0.x was a little rocky, so I'm going to document it again today - this time with a Hibernate 2.0-enabled version of XDoclet, and code samples from last time. Today I'm upgrading from 1.2.4 to 2.0 rc1.

1. First, I downloaded Hibernate 2.0 rc1. BTW, I also updated to the latest version of XDoclet from CVS.

2. Next, I copied it to my project's lib directory, deleted bin, doc, and src directories. The only files I need are hibernate2.jar and (in the lib folder) c3p0.jar, cglib.jar, dom4j.jar, jcs.jar, jdom.jar and odmg.jar. One thing to note is with Hibernate 1.2.x, I didn't need dom4j.jar, jdom.jar or cglib.jar in my deployed WEB-INF/lib folder. However, with the new version, I did need to include them.

3. Then I updated lib/lib.properties and began changing my code with gool ol' Homesite.

4. Hey, step 4 is the same as last time! Edit build.xml file to pick up the new DTD. I changed <hibernate/> to be <hibernate validatexml="true" version="2.0"/>.

5. Using HomeSite, I did s/cirrus.hibernate/net.sf.hibernate/g for all my .java and .xml files. Don't forget to change your log4.properties and hibernate.properties files.

6. In hibernate.cfg.xml I changed cirrus.hibernate.sql.OracleDialect to net.sf.hibernate.dialect.OracleDialect. I also updated the DTD to 2.0 and moved all properties inside the <session-factory> element. Here's a sample hibernate.cfg.xml file from struts-resume.

7. In my ServiceLocator.java class, I changed the following from (this is so JUnit Tests can run w/o JNDI):

Datastore datastore = Hibernate.createDatastore();
datastore.storeClass(package.MyClass.class); // lots of these
sf = datastore.buildSessionFactory();

To:

sf = new Configuration().addClass(MyClass.class) // lots of these
                        .buildSessionFactory();

8. Time to bring Eclipse to the table. I refreshed the project and added the new hibernate2.jar to the "Java Build Path."

9. In my StartupListener.java (which initializes Hibernate for Tomcat), I changed the following code:

// Configure Hibernate.
try {
    Hibernate.configure();

    if (log.isDebugEnabled()) {
        log.debug("Hibernate configuration completed.");
    }
} catch (HibernateException h) {
    log.fatal("Error configuring Hibernate!", h);
}

To:

try {
    SessionFactory sf =
        new Configuration().configure().buildSessionFactory();

    if (log.isDebugEnabled()) {
        log.debug("Hibernate configuration completed.");
    }
} catch (HibernateException h) {
    log.fatal("Error configuring Hibernate!", h);
}

10. Changed all instances of readonly="true" to inverse="false" inverse="true" for XDoclet tags. Also changed role to name.

11. Removed length attribute from any <key-property ... /> elements in my .hbm.xml files. These were rudely put there by the ReverseGenerator. Not all my mapping files are generated by XDoclet, if I have one with a composite-id, I just create the mapping file manually. I also had the change the DTD manually in these files.

12. In my build.xml, I changed the SchemaExport class from net.sf.hibernate.tools to net.sf.hibernate.tool.hbm2ddl.

13. OK, here goes, my first attempt at compiling (honestly!). Darn - I forgot to save StartupListener.java - trying again (this time with "ant clean" first). Sweeeet - it worked!

14. Hmmm, some log messages I wasn't expecting. I forgot to change my log4j.properties file from cirrus.hibernate to net.sf.hibernate. I'll add this above (step 5) to make this how to more accurate.

15. Running persistence tests - since I keep my Oracle driver (ojdbc14.jar) in ${hibernate.dir}/lib, I had to move it to the new directory. Now this is a strange error:

[junit] 2003-04-29 13:14:50,968 INFO [main] Configuration.addClass(264) | Mapping resource: com/
.../persistence/ChangeRequest.hbm.xml
[junit] 2003-04-29 13:14:51,234 ERROR [main] XMLHelper$ErrorLogger.error(37) | Error parsing XML
: XML InputStream(19)
[junit] org.xml.sax.SAXParseException: Attribute "name" is required and must be specified for el
ement type "param".

My guess is that it's being caused by:

<generator class="sequence">
    <param>cr_master_sq</param>
</generator>

After reading the Hibernate2 Porting Guidelines, looks like I need to add a name attribute. Didn't the exception tell me that! ;0)

I'll update this post when I figure out the answer to my question on Hibernate's forums...

Update: I had to 1) upgrade my XDoclet JARs, and 2) replace the following XDoclet tags:

* @hibernate.id column="cr_id" unsaved-value="null"
*  generator-class="sequence" generator-parameter-1="cr_master_sq"

with:

* @hibernate.id column="cr_id" unsaved-value="null" generator-class="sequence" 
* @hibernate.generator-param name="sequence" value="cr_master_sq" 

Now I'm experiencing this issue.

Update 2: I discovered (from Gavin) that readonly="true" is the same as inverse="true". I've updated step 10 above, and now my upgrade is complete!

Posted in Java at Apr 29 2003, 02:52:07 PM MDT Add a Comment

Validation vs. Business Logic

In the manuscript I'm reading, I just ran into a diagram and overview of a layered architecture - and all of a sudden, it hit me. At work, most of our business rules are being implemented by Struts' Validator framework. In the case of indexed properties and more complicated rules, these reside in the validate() method of our action forms. So it's interesting to me that I'm using a business delegate to perform my business logic - when in actuality, all my delegates are doing is copying properties from a POJO to an ValidatorForm. So this begs the question - shouldn't validation (a.k.a business rules) be done wherever it is most convenient rather than only in the domain layer? Oh yeah, and most of this is just validation - our real business rules (comparing data for validation) takes place in Oracle stored procedures. And you know what - it works great!. So my opinion is - do whatever is easiest and makes the most sense.

Posted in Java at Apr 29 2003, 06:18:27 AM MDT 6 Comments

This site's performance

This site crashes more than a 16-year old trying to pick up the ladies. You can check out all the errors in my catalina.out (3+ MB) file (snapshot from last night). Mostly OutOfMemory errors causing the issues. I'm going to try and configure jikes to run as my JSP compiler, we'll see if that helps. I'd like to try it locally first (on my Win2K machine), but it looks like I have to compile it with the -encoding option to make it work. Ughhh. Why don't they have an encoding-enabled download!?

Posted in Java at Apr 23 2003, 04:36:28 PM MDT 6 Comments

Struts + OJB Example at SourceForge

James Mitchell has contributed a modified version of Chuck Cavaness' Beer4All Shopping cart demo to the Struts' SourceForge Project. If you're looking for an example of using OJB with Struts, this is probably your best bet. From the struts-user mailing list:

Ok, just got off the phone with Chuck.  He said he doesn't mind, so here is
the version that I have:

  http://sourceforge.net/projects/struts/

Note - This is a simple webapp and not all the features have been
implemented.  I will continue to improve the codebase over the next few
months, but this is a "use at your own risk" sample application.

To deploy "as is", you will need to configure your database connection
(repository.xml) and create a database (or change the config) called 'ojb'
with a user 'ojb' and password 'ojb'.  Next execute the sql.sql against the
new database to create the necessary data and internal tables (OJB).

Use you best judgment to deploy on your container.  I can help if using
Tomcat, Resin, or JBoss/Tomcat.  Personally, I use JBoss/Tomcat so the
unzipped/exploded war should deploy if you extract it to
server/default/deploy.

Have fun!!!

--
James Mitchell
Software Developer/Struts Evangelist
http://www.open-tools.org

BTW, there are quite a few Hibernate example apps (appfuse, hibernate and struts-resume) at the Struts SF project as well.

Posted in Java at Apr 23 2003, 10:22:43 AM MDT Add a Comment

Locking Records in Webapps

Our tester, Roberto, started working at my day job today. This means that I've been hacking and interacting with Bugzilla all day. It's great to have someone to validate our code meets the requirements (BTW, all our requirements are kept in Bugzilla - how's that for dynamic requirements?!) So, as far as satisfying my desire to be a productive American, today has been a good day. After I ride home (~20 miles) tonight, I'll feel on top of the world. Anyway, back to the point of this post.

One of the bugs that Roberto entered was that a user could login using two separate browser sessions (same user), and blah, blah, blah. I'm sure anyone who's worked with webapps has seen this. You open a page up in both browsers, click "Save" in the first, and then "Save" in the second. The second browser overwrites the first one's changes. I've seen this bug many times, but I've never solved it, nor even tried.

I'm curious to know if any of you have solved this? I think Hibernate has a way of locking an object - but will that solve this issue? I'm willing to implement a quick solution, otherwise, I'll argue the bugs validity until I'm blue in the face. Hmmm, I wonder if I can simply use Struts' Tokens feature to solve this problem? Please hook me up if you've solved this problem in your webapps.

Posted in Java at Apr 21 2003, 05:07:24 PM MDT 4 Comments

Upgrading to Roller 0.9.7

I'm starting the upgrade to Roller 0.9.7. Don't stand by with too much earnest - if I get interrupted by Julie and Abbie - they have priority. I'll let you know when I'm done.

Later: I might as well keep a record of what I do to upgrade so it'll be easier next time - and maybe I'll eventually write a script to do it all.

1. I dumped the mysql database from this site using mysqldump. I then created a database locally and imported it.

2. I ran the 0.9.6 to 0.9.7 upgrade script for mysql. I encountered a few errors as I was partially on 0.9.7 already.

3. I edited the log4j.properties file to e-mail me errors and to cut down on Velocity and Hibernate logging. I also got rid of the "R" appender, as that was writing a roller.log file that is essentially the same as Tomcat's log file. I also added timestamping to the log messages.

# Properties for configuring Log4j for this application
# This is the configuring for logging displayed in the Application Server
log4j.rootCategory=INFO, stdout, mail

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%d %C{1}.%M(%L) | %m%n

# Configuration for receiving e-mails when ERROR messages occur.
log4j.appender.mail=org.apache.log4j.net.SMTPAppender
[email protected]
[email protected]
log4j.appender.mail.SMTPHost=localhost
log4j.appender.mail.Threshold=ERROR
log4j.appender.mail.BufferSize=1
log4j.appender.mail.Subject=[www] Roller Application Error

log4j.appender.mail.layout=org.apache.log4j.PatternLayout
log4j.appender.mail.layout.ConversionPattern=%d [%t] %c %x - %m%n

# If programmed properly the most messages would be at DEBUG 
# and the least at FATAL.

# Options are: DEBUG, INFO, WARN, ERROR, FATAL
log4j.logger.org.roller=ERROR
log4j.logger.org.apache.velocity=ERROR
log4j.logger.org.apache.commons=ERROR
log4j.logger.org.apache.struts=ERROR

# All hibernate log output of "info" level or higher goes to stdout.
# For more verbose logging, change the "info" to "debug" on the last line.
log4j.logger.net.sf.hibernate.ps.PreparedStatementCache=ERROR
log4j.logger.net.sf.hibernate=ERROR

4. Whoa! There's a new look to the index.jsp page. I corrected a small bug in the link around the combined rss badge.

5. I changed oscache.properties to have a "cache.path" that was prudent for my installation.

6. Added home.jsp and changed "main" forward in struts-config.xml to have a path="/home.jsp" so users will be directed to this page, rather than the index.jsp.

7. Onto synchronizing my current web.xml with the new one. Added <welcome-file-list>, <error-page>'s and security settings for my private weblog. Sweet, JSTL has been added so I don't have to add these taglibs or jars. I changed the <form-error-page> to "/login.jsp?error=true". Funny thing is, I never see the login page anymore since I'm using the "Remember Me" feature.

8. Added all custom images from my about page to the "images" directory. Also moved my custom favicon.ico from backed up directory to new roller installation directory.

9. Next, I synched up the settings from my roller-config.xml file with the new one. FYI, e-mailing comments is off by default.

10. Now I guess I need to convert all my pages to use the new macros. I'll do this after upgrading the codebase here. It's kindof a pain to upgrade the codebase, as you've already seen. One of my problems is I have symlinks all over the place in my "roller" directory, so rather than re-creating them, I just upload a .jar of roller, unzip it, and cp -r roller/* webapps/roller/. over my last installation. Crossing my fingers now.

After upgrading code: It looks like I changed the wrong forward, rather than "main", I should've changed "home.page" to home.jsp. I'll let you know if I spot anything crazy while attempting to do my macro migration.

Update: After the macro migration, the only issue I've found (so far) is that #showWebsiteTitle() adds spaces on both ends, and since I'm writing this using JavaScript (for the title image), it's screwing things up. I reverted back to $macros.showWebsiteTitle() and everything works as expected. Now I just have to figure out how to get trackback setup. I tried this, but it didn't work for me. Also, I can't seem to get #showAllNewsfeeds(true 1) to work.

Posted in Roller at Apr 20 2003, 11:10:26 AM MDT 3 Comments