December 13, 2002

A Reader Comments

After much anticipation, the book is now available, both from SAMS (with $8 overnight shipping!!), and Amazon.  Readers are already beginning to comment:

From: Ron Day [mailto:ronday@ronday.cc]
Sent: Friday, December 13, 2002 10:55 AM
To: Struts Users Mailing List
Subject: RE: [ANNOUNCE] Shameless Plug: Struts Kick Start now  available for shipping at Amazon

I'd like to second what Kevin has said.

I have bought and read every book on Struts, in the order  that they were published. I got Kick Start this Wednesday.  (Sams sent it overnight for $8.). My three favorite books are  Chuck's, Ted's and Kick Start. All three are different, have  the personalities and interests of the authors, and offer  three perspectives on Struts development and best practices.  I would be very hard-pressed to choose just one, but since I  love tech books that isn't an issue for me. All three are  intermediate to advanced texts (for more intro material, look  at "Mastering Struts" ). If I had to give one reason for  buying Kick Start, I would say "for the excellent chapters on  Struts Tags". The other books do not dwell on the Tags, while  KickStart has a detailed chapter on each library.

Ron

Posted by blackbear at December 13, 2002 10:55 PM | TrackBack
Comments

I'm trying to get my first struts app working. Here is my ActionClass:::


import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;

import org.apache.struts.util.MessageResources;
import org.apache.commons.beanutils.PropertyUtils;


public final class HomeAction extends Action {

public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {

MessageResources messages = getResources(request);

return (mapping.findForward("GoHome"));
}
}


---------------------------------------------

I get a compilation error stating:
getResources() in org.apache.struts.action.Action cannot be applied to (javax.servlet.http.ServletRequest)
----------------------------------------------

Any ideas?

Posted by: Mark on January 13, 2003 11:15 PM

Which version of Struts are you using? The
getResources(HttpServletRequest) method was only added to Struts recently.

Posted by: James Turner on January 13, 2003 11:29 PM

I was following Step 2: Install MySQL (p 450). All went well until I run
c:\mysql -u demo -p stocktrack
when "Enter password:" appeared I typed
"struts"
but mysql exited with error message
"ERROR 1045: Access denied for user: 'demo@localhost' (Using password: YES)"

My PC was Windows 2000 Sp3.

Thanks in advance.

Posted by: xg on February 5, 2003 09:05 AM

First, let me say thank you I am enjoying the book so far!

I have some errata to report. Pls. excuse me if this is not the correct place to report it. I did not see any other way.

When I performed Step 2: Install MySQL from Appendix A, the command "mysql -u demo -p stocktrack" and entered struts as the password the login failed. I had to modify the init_database.sql to remove the single quotes around the username (demo@localhost and demo) and change the single quotes around the password to double quotes. After this modification and re-ran the script, I was able to login using the command in the book and execute the populate_database.sql script. I am using MySQL version 3.23.27-beta on Windows NT.

I ran the stocktrack application from Ch. 11. When I click on the link to create an account on the main page, I get the following error: HTTP Status 404 - /newaccount.do. If I use the following URL: http://localhost:8080/stocktrack/newUserName.do I am able to create an account.

Can you please make the build files available for the Ch. 11 version of stocktrack and the other applications in the book?

Posted by: Gary Blomquist on February 5, 2003 09:24 PM

I was unable to access the web pages from the TabLib app in Ch. 12. Upon viewing the Tomcat window, I saw the following error:

Apache Tomcat/4/1/12
WebappClassLoader: validateJarFile(E:\jakarta-tomcat-4.1.12\bin..\webapps\Taglib\WEB-INF\lib\servlet.jar) - jar not loaded. See Servlet Spec. 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class

Also, note that the URLs in Chapter 12 of the book erroneously refer to this web app as StrutsTabLibs instead of Tablib which is the name of the jar file.

Posted by: Gary Blomquist on February 6, 2003 10:15 AM

Nice book!

Errata:

Listing 3.1 - hello.jsp

html:form tag focus="username" attribute should be focus="person".

Marcus

Posted by: Marcus Caton on February 13, 2003 02:20 PM

In later versions of torque (torque-3.0-b4, torque-3.0-rc2), a new class called Transaction suddenly appears in the org.apache.torque.util package. This basically breaks the ejb code generated for the book's Stock Transaction Application.

One of the schema tables is also called Transaction, and the code will now make ambiguous references to two different Transaction classes. The easiest way to fix it is to modify the schema XML to change the name of the table to something like "STOCKTRANSACTION." The code will be generated with this new bean name and subsequently compile without error.

Posted by: Charles Arcudi on February 15, 2003 01:41 AM

The strutsANT/build.xml file in the windows install contains two bugs. First you tweek the build.properties file. There is only vague comments that this would be appropriate compare "placing bin in directory in your path" [p450] (not explicit hand holding, but we can all put a value in path),
no is made to go tweek this file anywhere but in the build.xml "Any host specific should be defined in the build.properties." And since the install puts tomcat in c:\Program Files\Apache ...
Why am I tweeking this file in the first place!
Your installation is not self consistent.

So on to more serious problems once I set the value in build.properties.
1. > ant build
doesn't work 'cause the classpath in strutsANT/build.xml includes
${tomcat.home}/lib which is not in the installation and mentions
{tomcat.home}/classes which is also not in the installation.

Since you put them all on the CD you might know where they would typically end up so the build.properties not being set seems silly. Whats with refering to dirs in your own tree which don't exist?

Then the book page 428 says "doc" target when the actual target is "javadoc"; a minor typo. But the "javadoc" target spews all kinds of weird stuff about:
"this sentence is different thn what would be generated using -breakitereator
and
package org.apache.struts does not exist
package javax.servlet.action does not exist

Hmm doesn't seem to be a complete configuration for that target, yet since this is supposed to be my first build.ant file (or is it my last since it is chapter 20 in the book). Fixing it seems perplexing
for the beginner.

Just a few errata.

-Paul

Posted by: Paul on February 20, 2003 12:14 AM

The ejb classes generated by torque in my installation do not use NumberKey variables to address the bean primary keys. They are "int" primitives instead. Your example code seems to have been generated with NumberKey. Any ideas why this might be?

I'm trying to follow along and build the app as I go. Guess that is a prescription for frustration, but it is interesting to see the anomalies along the way.

Posted by: Charles Arcudi on February 20, 2003 11:38 PM

Make sure you're using the version of Torque that comes in the book on the CD, the latest versions of Torque changed to int for primary keys.

Posted by: James Turner on February 21, 2003 12:00 AM

I just stopped by to say thank you for delivering such a superb overview of the Struts framework (and for such a great price!). Recently, I have been working (very dubiously) to break away from the "procedural" programming nightmare that many web developers today currently live in, and there is no better starting point than Struts.

More importantly, I want to emphasize that while many readers of this book are probably java servlet or JSP developers, I am not. Although I thoroughly agree that Struts is a great starting point for web apps, I believe what Struts brings to the table is a model all web developers which can follow, even those who use PHP (like myself). Unfortunately I cannot switch to Java on my current project, but I can certainly stand on the shoulders of giants to apply these concepts to PHP (I am working on a port similar to Phrame, picking up where it left off).

My point is, I believe that all (serious) web developers should own this book, even if Perl, PHP or ASP is their language of choice. The design of Struts is a solution to a problem that has gone unsolved for far too long.

Posted by: Dan Allen on February 21, 2003 03:55 AM

The latest version of torque has made some changes to its connection and DataSource configuration. To get the stocktrack app (for example) to work with this version, you need to tweak the Torque.properties file.

Say you've created a mysql db called stocktrack .

In the section labelled:
# -------------------------------------------------------------------
#
# T O R Q U E P R O P E R T I E S
#
# -------------------------------------------------------------------

change the first three properties like so:

torque.database.default=stocktrack
torque.database.default.adapter=mysql
torque.database = stocktrack

Pick a dsFactory to use (say the JDBC2 version) and modify the set of properties for that dsfactory like so:

torque.dsfactory.stocktrack.factory=org.apache.torque.dsfactory.Jdbc2PoolDataSourceFactory
torque.dsfactory.stocktrack.pool.defaultMaxActive=10
torque.dsfactory.stocktrack.pool.testOnBorrow=true
torque.dsfactory.stocktrack.pool.validationQuery=SELECT 1
torque.dsfactory.stocktrack.connection.driver = org.gjt.mm.mysql.Driver
torque.dsfactory.stocktrack.connection.url = jdbc:mysql://localhost:3306/stocktrack
torque.dsfactory.stocktrack.connection.user = whatever-the-user-is
torque.dsfactory.stocktrack.connection.password = whatever-the-password-is

The trick is to make sure you replace the supplied value "default" with the database name.

If you neglect to do this, you will get a very cryptic (and extremely frustrating) NPE that reads like so:

22:28:12,948 ERROR [STDERR] java.lang.NullPointerException: Connection object was null. This could be due to a misconfiguration of the DataSourceFactory. Check the logs and Torque.properties to better determine the cause.

... which, for want of a more politic term, is useless.

Of course, if you use the version of Torque supplied with the book, you won't have any of these problems. But where's the fun in that?

Posted by: Charles Arcudi on February 28, 2003 02:04 AM

The hello.jsp (ch03 or strutsJUNIT) has a form
action of HelloWorld.do?action=gotName
but the TestHelloActionMultiple.testBadPerson()
and the TestHelloActionMultiple.testHappyPath()
Both have
addRequestParameter( "action", "getName" );
gotName/getName what's with that?
I search the entire strutsJUNIT project and the only occurance of getName is in a comment in HelloAction.java.

After close examination you might realize that the parameter **value** is meaningless. Setting it to 'foo' would work as well. The value of the parameter is not used in the Action code anywhere, so it's a typo in the setting of parameter in the test vs. the actual jsp. Just another typo amongst many to throw you off while trying to step through
your first set of struts applications.

-Paul

Posted by: Paul on March 4, 2003 11:45 PM

Getting this error, which I'm begging to believe is Container-specific (Jetty w/ JBoss). Any idea what it might mean:

21:35:00,703 ERROR [STDERR] org.apache.torque.TorqueException: IdGenerator for table 'ADDRESS' is nu
ll
at org.apache.torque.util.BasePeer.doInsert(BasePeer.java:690)
at stocktrack.torque.BaseAddressPeer.doInsert(BaseAddressPeer.java:213)
at stocktrack.torque.BaseAddressPeer.doInsert(BaseAddressPeer.java:510)
at stocktrack.torque.BaseAddress.save(BaseAddress.java:794)
at stocktrack.torque.BaseAddress.save(BaseAddress.java:756)
at stocktrack.torque.BaseAddress.save(BaseAddress.java:736)
at stocktrack.struts.action.NewUserAddressAction.perform(NewUserAddressAction.java:96)
at org.apache.struts.action.Action.execute(Action.java:415)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:465)

at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1422)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:523)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:366)
at org.mortbay.jetty.servlet.WebApplicationHandler.dispatch(WebApplicationHandler.java:293)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:581)
at org.mortbay.http.HttpContext.handle(HttpContext.java:1687)
at org.mortbay.jetty.servlet.WebApplicationContext.handle(WebApplicationContext.java:544)
at org.mortbay.http.HttpContext.handle(HttpContext.java:1637)
at org.mortbay.http.HttpServer.service(HttpServer.java:875)
at org.jboss.jetty.Jetty.service(Jetty.java:543)
at org.mortbay.http.HttpConnection.service(HttpConnection.java:806)
at org.mortbay.http.HttpConnection.handleNext(HttpConnection.java:956)
at org.mortbay.http.HttpConnection.handle(HttpConnection.java:823)
at org.mortbay.http.SocketListener.handleConnection(SocketListener.java:203)
at org.mortbay.util.ThreadedServer.handle(ThreadedServer.java:290)
at org.mortbay.util.ThreadPool$JobRunner.run(ThreadPool.java:743)
at java.lang.Thread.run(Thread.java:536)

Posted by: Charles Arcudi on March 11, 2003 12:45 AM

The disc that came with my book does not contain the strutsEJB.zip file for the application in Chap 18. Is there a site from where this can be downloaded?

Posted by: Tony Merolla on March 14, 2003 09:50 AM

nice article, keep up the good work. lookup zip code

Posted by: zip codes on March 15, 2003 07:57 PM

CustomerValueObject?

And by this, we tightly couple two completely separate implementations (strutsEJB.jar, strutsEJB.war). Works fine if you plop them into two separate VM's, but should you try to put the two together, the class loaders will detect a change in the hashcode between the "duplicate" classes and throw a ClassCastException. Lovely.

The same thing could have been accomplished with a Map or a Properties object.

Modifying the "FacadeObject" to swap between client customer value objects and properties objects achieves the same result.

You can then deploy to JBoss with Jetty, JBoss with Tomcat or JBoss with a separate Tomcat installation.

Posted by: Charles Arcudi on March 15, 2003 11:43 PM

Value Object is a J2EE Design pattern.

An odd choice for a specification, but there obviously must be a reason.

Posted by: Charles Arcudi on March 16, 2003 04:48 PM

Dear Sir:

I am new to Struts. I bought your book recently. I start to build up my own struts application while I am reading it. I have a problem with uploading file. Based on the code you provided in Chapter 12, P248. In Action class, you have upload directory. The source code is
MessageResources messages=getResources(request);
String dir = messages.getMessage("save.dir");

I think save.dir is upload directory. If I have "doc" directory to save uploaded file, How should I do it? I have spent a day to figure out, but cannout make it work. Can you help me? Thank you.

Posted by: Juan Fu on May 19, 2003 05:21 PM

nice article, keep up the good work. lookup zip code

Posted by: zip codes on June 19, 2003 12:23 PM

can any body help me ...
i am using the pub/sub to implement the message queue with tomcat4 but when i am trying to put the message in message queue through a jsp page i am getting this error ...


type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

org.apache.jasper.JasperException: javax/jms/Session
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:254)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2415)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:594)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:392)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:565)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:619)
at java.lang.Thread.run(Thread.java:536)


root cause

javax.servlet.ServletException: javax/jms/Session
at org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:536)
at org.apache.jsp.engine_jsp._jspService(engine_jsp.java:56)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:137)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:210)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2415)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:594)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:392)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:565)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:619)
at java.lang.Thread.run(Thread.java:536)

--------------------------------------------------------------------------------

Apache Tomcat/4.1.24-LE-jdk14

Posted by: Dharmendra on June 23, 2003 05:52 AM

more comments are needed here.

Posted by: carfacts on June 23, 2003 05:17 PM

I recently bought the book and try to run the hello world from ch3 on cd. I don't see a hello.war file in ch3. Do I need to copy the whole directory to my webapps dir and restart tomact. And in the installation steps it doesn't tell about installing struts. Don't we need to explicitly install struts?

Thanks
Praveen

Posted by: Praveen on July 7, 2003 05:58 PM

lol!

Posted by: dvd on August 26, 2003 04:07 PM

Hi,
I am reading book online at Safari Books Online. I am looking for the sample app source code online. I could not find it on the publisher's site and your site as well.
The more important ones are the sql scripts, I can write the java code myself, when I read the book. Is there some placce I can download the scripts. Any response will be appreciated.
thanks
Sudhakar

Posted by: sudhakar on August 27, 2003 11:01 PM

Why there are so many errors in this page?

Posted by: visual basic on September 15, 2003 02:06 PM

Thank God I found your site!

I've been trying to build a struts/tiles/torque-based website for a professional orgainzation and was completely stumped by the DataSourceFactory misconfiguration.

Finally, a google search of "struts DataSourceFactory" took me right to your site, and thence to a solution.

If you're ver in Atlanta, please let me buy you a beer.


Patrick Carroll
--

Posted by: Patrick Carroll on September 18, 2003 07:16 PM

interesting

Posted by: tom on September 24, 2003 05:25 PM
Post a comment