Dr. Hacker (March, 2002)
Home Schedule Prime Directives Engineering Log Coding Standards Software Submission Checklist Dr. Hacker

 

3/1/2002

> Dear Dr. Hacker,
>
> For the assignment that is due March 13 (ICS613) I have one question.
>
> How should we name the project in CVS? It would not be a good idea
> if all the students name it "accountinfoMVC". What about
> "accountinfoMVC-"?
>
> -- Name-aste
Let's continue with the approach from the prior assignments and put the username first (i.e. -accountinfoMVC). But yes, of course, each group has to come up with a unique name.
> Dr. Hacker,
>
> I don't think the Singleton pattern is appropriate here. The effect is
> equivalent to an application bean. If you fire up two browsers, you will
> find they interfere with each other. What is really wanted is something like
> a session bean. Thanks.
>
> -- Thinking EJB
I thought I went over this in class, but maybe I forgot to talk about it in the 613 section. Whether or not the singleton pattern is an appropriate design for the StackModel depends upon what the purpose of the application is. If the purpose of the application is to allow all users simultaneous access to a single stack instance, then the singleton pattern is perfectly appropriate. If the purpose of the application is to provide each user with their own stack instance, then the singleton pattern is not appropriate (instead, you need to maintain session state, which I will go over next week.)

It's not important to argue over what "should" happen here, because, of course, no one really wants access to a stack over the web, either personal or shared! What you should get out of StackModel is how to implement a singleton pattern, which is something that could very well come up on a midterm or final, as well as in innumerable application contexts.

Here's some interesting (optional) further reading on Singletons in Java:
http://members.tripod.com/rwald/java/articles/Singleton_in_Java.html - provides some additional machinery to deal with subclassing
http://developer.java.sun.com/developer/qow/archive/111/ - using readResolve to make a singleton serializable
http://www.javaworld.com/javaworld/jw-01-2001/jw-0112-singleton.html - how to avoid multiple singletons (I've had this problem myself!)
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66531 - the "Borg" DP, proposed as superior to Singleton (Python version)

 

Cheers, Dr. Hacker

3/3/2002

Dear Readers,

Just a friendly reminder to continue maintaining your engineering logs. Even the throwaway assignments on stackMVC can have engineering log entries! And of course your accountinfoMVC assignment should have log entries.

> Dear Dr. Hacker,
>
> For the accountinfo assignment, various people will probably be starting with
> the same baseline, but diverging immediately. If they are all committing the
> same module, they will cause problems. In such a circumstance, should we
> input a separate module or make a branch of the original module? I've tried
> making a branch, but it's weird and I don't know if I did it right.
>
> -- Clobbered by Science
Hmm. I forgot about the possibility of multiple groups want to choose the same accountinfo package to work on. In normal circumstances, the right solution is to create a branch. Working with a branch requires you to be somewhat more on top of things with your checkouts and so forth, but is otherwise not that difficult. Here's a pointer to the standard CVS documentation:

http://www.loria.fr/~molli/cvs/doc/cvs_5.html#SEC49

You will also want to consult the WinCVS (or whatever client you're using) for client-specific details.

Another solution is to: (1) Make a distribution of the accountinfo module you want to use. (2) Import this distribution into CVS with a new unique module name (perhaps using both partner's emails to guarantee uniqueness, or call it accountinfo3 or something.) Make sure you import the files 'ant' and 'setenv.csh' as binary by manually overriding the default text interpretation so that they do not have Windows line endings.

Finally, remember that you are now working on two components: accountinfo and accountinfoMVC. These should be maintained in two independent CVS repositories. The accountinfoMVC system will include an accountinfo.jar file in its distribution with the latest release of this component.

If you remind me on Monday, we can take a poll in class and see how many groups intend to use the same module.

Cheers, Dr. Hacker

3/5/2002

> Dear Dr. Hacker,
>
> Our web app has a command for displaying the contents of an account object,
> listing the account name, first name, last name, etc. So how should the model
> report that back to the command? It could pass back an Account object, but
> that seems to break the boundary between the model and controller. Doesn't
> it? We could pass back a big String holding everything, but that seems rather
> repugnant. We could send back an array of Strings, each representing a field
> of the user object, but that seems to expose things and make even nastier
> dependencies. We could make a whole new class, just for passing values
> between model and control, but that doesn't appeal to me much.  The simplest
> appeals to me - just return an Account. Then the command will put each field
> in the request object as a String with an appropriate property name.  Or
> maybe an immutable variant of the Account object?
>
> -- No account hacker
I suggest that you do it the simple and straightforward way and set an attribute in the request object to the actual account instance. BTW, if you read through the core taglib documentation, one of the features you'll come across is the ability to refer to the get* properties of an instance through a dot notation. For example, say you have a class such as the following:
  class Foo {
   :
   public String getBar ()
   public String getBaz ()
  }
Then, if "element" is bound to an instance of a Foo, you can access the "bar" property with element.bar and the "baz" property with element.baz. This avoids the need to set multiple attributes in the request object to all of the properties you want to access.

If it's the case that you only want certain properties of an Account object to be accessable from the JSP page, then you want to create a "view" of it. One nice way to do that is with interfaces.

Cheers, Dr. Hacker

3/7/2002

> Dear Dr. Hacker,
> 
> I was wondering how much is java used in the professional world?  Through
> classes, such as this one, I am convinced that Java is THE language to use
> for software engineering.  However, in my interviews they only ask about my
> C/C++ skills.  I have yet to come across a employer asking about java.  Given
> that I have not had that many interviews, i still think this is a bit odd.
> 
> So, that brings me back to the previous question, how much is java used in
> the professional world.  If the answer is "a lot," (which i think and hope it
> is) then my question is that what kind of jobs are they and where are they?
> The reason for these questions is that i am worried.  I am worried that my
> educational focus has been on the wrong language (I know that this can not be
> true).  So, i am just worried.
> 
> A couple more questions:
> Am I seeing this all wrong?
> Is this a crazy thing to be worried about?
> What kind of companies and jobs are out there for a java programmer?
> Where is a good place to start looking for a java job?  Well, besides
> google... i tried that already.. i need a little bit more direction that
> that...
> 
> -- Professionally challenged
This is a good question. Here are some perspectives:

First, Java is a very young language, and computers have been around a long time. There is anecdotal data that suggests that the most "popular" language (in terms of code actually in use today) is... COBOL! Furthermore, many (particularly entry level) programming jobs mainly involve maintaining programs written in the past. In those circumstances, the odds are against those programs being written in Java, simply because the language may not have been around at the time the program was originally written.

Second. On the other hand, Java is a very good language for many things, and there are many, many jobs out there for Java programmers. At Monster.com, I just did a quick keyword search and found that more job listings involve Java than any other programming language I tried:

Keyword            Jobs
Java               3780
Visual Basic       2057
C++                1378
COBOL               865
.NET                292
Fortran             211
C#                   59
Lisp                 20
Third. In general, in order to improve your marketability, it is good to be proficient in more than one language. Don't limit yourself to just learning Java. From the data above, it would be good to know all three of Java, VB, and C++.

Fourth. To find jobs, it is very important to network. For example, the Hawaii Java Users Group just had a meeting where the topic was about interviewing for Java jobs. A great deal of useful information came out at that meeting about how to search for tech jobs in Hawaii at this point in time. I hope you were there. The job search issue is a big one and I can't begin to get into it in this email. Maybe we'll have a session on it one day in class.

Fifth. Finally, and I can't emphasize this enough: if you become truly *expert* at a particular language or application area, then you will have gained insights that you can transfer to any other language or application area and use to become proficient in a relatively small period of time. "Expert" is a hard word to define operationally, but one reasonable heuristic for Java might be having written and released 200K-300K lines of code in a particular domain for public use and evaluation. In other words, you don't get to be "expert" by having taken ICS 413/613. You get to be expert by (maybe) having taken ICS 413/613 and having followed up by spending the next couple years of your life seriously hacking.) Some programmers never get to be experts in anything; they just dabble away the years. For example, I've been playing guitar regularly for over 20 years and am a bit embarrassed to confess that I am still not an expert guitar player and it doesn't look too good for the immediate future, either. Similarly, it doesn't matter how *long* you've known Java or C or whatever; you can dabble in a language for years and still not be an expert from my perspective.

The point I'm trying to make is that you have to balance the benefits of having broad exposure to multiple languages and areas with the benefits of having deep knowledge and understanding of single language and/or narrow area.

Cheers, Dr. Hacker

3/8/2002

> Dear Dr. Hacker,
>
> Do we need to create a toArray() in our original accountinfo so
> that we can access the database where all the accounts is stored?
> We need to get access to the database, but you also said that we
> shouldnt let other developers know that we are using a TreeMap.
> Is there a more efficient way to gain access to the database of
> accounts?
>
> -- Don't like copying
Boy, I'm glad you're asking that question. Everybody listen up: the toArray() technique used in StackMVC is NOT scalable! It makes a *copy* of the *entire* stack in a new array and passes that to the JSP page.

You may be asking yourself: so why did he choose such an incredibly lame and space-inefficient approach that would never be used in a real-life information repository situation? The reason is because I wanted to preserve the semantics of the stack data structure. A stack, by definition, does not allow access to its innards: you can only push and pop (although top is typically an allowed extension). If I provided an iterator() method in Stack, which would be the obvious and efficient solution, then it wouldn't really be a stack anymore. My solution to preserving the semantics was to provide a method that creates a new data structure (an array) that happens to have the same contents as the stack it came from at the time. (One could definitely argue that I still violated the semantics of stack by including this as a public method in the Stack class. A better approach to preserving the semantics would have been to provide another class, called something like "stackToArray", which takes a stack in its constructor and just uses stack pushes and pops to build a replicated array. (This would have been even more inefficient, and it seemed to get in the way of the purpose of the example, so I didn't go there.))

Now, in the real world, as opposed to History of Data Structures Class, we design ADTs so that they function correctly and as efficiently as possible for their clients' needs. If a client needs, for example, to iterate through the contents of the ADT, you don't make a copy of the entire repository as an array. Instead, you typically provide an iterator() method that returns an Iterator over the contents of the repository to the client.

And, it turns out that the tag accepts an Iterator as the value of the items parameter, which makes life absolutely fabulous:

* http://jakarta.apache.org/taglibs/doc/standard-doc/standard-ea3/IteratorTag_Fun ctionalDescription_2_EAI.html

Now that we've cleared up this issue, I will consider it a design error and take points off if I see avoidable copying of data structures in your accountinfoMVC solution. Next time, I'll just add the darn iterator() method to the Stack data structure and not be so fussy about semantics.

Cheers, Dr. Hacker

3/9/2002

> Hi Dr. Hacker,
>
> Can we make all the classes and methods in accountinfo.jar public?
>
> Currently, the accessor methods of Account class is protected. Therefore,
> we not able to use the getName() method in the accountinfoMVC. I have been
> thinking about how to solve this problem.
>
> 1. make all the protected methods to public.
> 2. I can extends my StudentModel, FacultyModel and AdministratorModel to
> Account class.
>
> In the addAccount(Account account) of AccountInfo class, we pass in an
> Account object, which can be student, faculty or administrator.  However,
> the Student, Faculty and Administrator is private class. I can not initial
> the object outside the package. Please advice.
>
> -- Visibility is opaque to me
Making "all the classes and methods in accountinf.jar public" is probably not the right thing to do. In any system, you want to try to hide certain implementation details, and the way you do that is to make certain methods (or classes) private or protected.

That said, it is certainly the case that *some* classes and methods need to be public. If they aren't, then you don't have an interface---something that can be invoked by clients in other packages.

I think it makes very good sense to make the Account class public. I would assume that at least some of the methods in your system will be private (or package private). But it depends at the end upon your specific design.

> Dear Dr. Hacker,
>
> I've been assuming "No" for this all this time, but it kind of keeps gnawing
> at me.  The requirements don't say anything about implementing a singleton
> pattern in our AccountInfoMVC, but are we supposed to?
>
> -- Singled out
If what you mean by "supposed to" is "will I get graded off if I don't", the answer is no. (You won't get graded off if you do, either.)

But I would rather think about "supposed to" in the context of the software itself. Where are we heading with this? A natural direction is an in-memory representation of account information that can be used for logins, registration, and so forth. For this particular situation, you would want to make sure that every client of the web application accesses the same instance (If you create a new instance each time you access it, then the mechanism is bogus.)

To make sure you get the same instance each time, you could go at least two possible directions. First, you could implement a singleton, so that there is only one instance total. Second, you could allow multiple instances, but provide a way for an application to "name" the accountinfo instance that they want to use out of all the ones that are currently created and then retrieve it when they need it. (This approach is cool in the context of distributed applications, where the accountinfo directory may not exist on the same server as the web application (or where multiple web applications want to access the same accountinfo directory.) Check out JNDI (Java Naming and Directory Interface) for a generic approach to this problem.)

Cheers, Dr. Hacker

3/10/2002

> Dear Dr.Hacker,
>
> Now our acocuntInfo MVC is running,but we still want to make sure one
> design issue.Should we also have an AccountModel besides AccountInfoModel
> class? Becasue we think the AccountInfoModel class will have the
> manipulations over Account container,such as Add,Modify and Delete,but the
> "CreateAccount" actually is different from those manipulations,maybe it
> needs another AccountModel? Or we can simply put "CreateAccount" into
> AccountInfoModel?
>
> -- I want to be a super model
The motivation behind the StackModel class was to provide a "wrapper" around the stack ADT that implements the singleton design pattern. For convenience, I added a "facade" interface so that you could manipulate the internal (singleton) stack instance via operations on the (singleton) StackModel.

In your case, you might want a singleton AccountInfo ADT, and so you could have an AccountInfoModel class to provide a similar wrapper. But since you want to have more than one Account instance, you don't need an AccountModel class.

I'm not sure what your CreateAccount method does, so I don't know whether it's appropriate. It would be appropriate in AccountInfoModel to have a method called "add" that takes an Account instance as its parameter and attempts to add it to the underlying singleton AccountInfo ADT, throwing an exception if a problem occurred (such as an account with the same name already in the data structure). It would certainly not be appropriate to have a CreateAccount method that takes string values corresponding to the components of an Account and creates the account internally. (We've gone over the reason why this is a bad design decision in class a couple of times already, and I'm now grading off pretty heavily if people continue to design their system this way.) If your CreateAccount method takes a single Account parameter, then it probably should be named "add", or "addAccount".

> Dear Dr. Hacker,
>
> I firstly tried to include an accountinfo1.jar file, but I feel
> inconvenient to modify and make a copy of accountinfo1.jar each time I
> want to change the interface of accountinfo1. So now I am maintaining
> these two packages in a same project, these two packages are
>
> edu.hawaii.chenx.accountinfo1
> edu.hawaii.chenx.accountinfomvc
>
> And my structure in JBuilder6 is like this:
>
> src
>  |
>  |-- accountinfo1
>  |__ accountinfomvc
>           |
>           |__control
>           |__modle
>           |__util
>
> Is this also acceptable?
>
> -- One module is better than two
Sorry, it's not acceptable. I was quite clear in the requirements that you need to keep accountinfo as a component. The fact that it's "inconvenient" is a good learning experience for you: developing systems as independent components is harder than it seems.

Component-based development is a very important skill to learn. By keeping accountinfo (the ADT) and accountinfoMVC (the web application) in separate CVS modules, you facilitate reuse of the ADT in other development contexts. Perhaps I might decide to develop a swing-based application that uses accountinfo next week. Do we just add that in to the module as well? If we keep on going down this path, pretty soon we'll have a massive system with parts that are totally unrelated except for the fact that they use the accountinfo ADT. Clearly this is bad.

Some good software engineering practices do turn out to be "inconvenient" in the short term. Another example is declaring methods private. It would be more "convenient" in the short term to just declare everything public, right?

> Dear Dr. Hacker,
>
> When I run my TestAddCommand I have methods that add a valid
> Administration, Faculty, and Student account.  The weird thing is that
> when I use the "restart.bat" file to start up my system the 3 accounts
> that were added from TestAddCommand are in my accountinfo data structure.
> Oh wait.. that's not the weird part.  The weird part is that I couldn't
> just say the following at the end of each method to delete the account
> I added in the test:
>
> AccountInfoModel.getInstance().delete(accountName);
>
> I had to do the following to delete the account:
>
> // Get the initialized delete page
> String initDeleteUrl = testHost +
>                        "accountinfo1mvc/controller?CommandName=InitDelete";
> response = conversation.getResponse(initDeleteUrl);
> assertEquals("Checking initialized delete page", deletePageTitle,
>              response.getTitle());
>
> // Deletes the account that was just added
> WebForm deleteForm = response.getFormWithID("DeleteForm");
> WebRequest deleteRequest = deleteForm.getRequest();
> deleteRequest.setParameter("accountName", "Test1");
> response = conversation.getResponse(deleteRequest);
>
>
> That might not make sense, since you don't know how our system is
> structured, but do you have any idea what is causing this?
>
>
> Another thing, should I consider that people will not use the
> "restart.bat" file to start up the system?  Cause if they don't use the
> "restart.bat" file to start up the system, I won't need all of that extra
> code in my Test methods to delete accounts after I add them.
>
> -- Dazed and confused
OK, there's three separate issues here:
  1. Accounts still exist after running restart. This is "impossible"--there's no such thing as magical persistence. Are you succeeding in stopping Tomcat? Are you succeeding in deleting the webapp? There is something wrong with your understanding, so keep looking at it. (BTW, it is extremely common to encounter "impossible" situations---that happens to me all the time in debugging. It just means you have to keep struggling to uncover the mistake in your model of the problem and the context.)
  2. Calling delete(accountName) doesn't delete the instance. Well, this "issue" may explain issue (1). The problem is that you don't yet understand that you've moved to a client-server environment. In this system, there are two java processes running. One of them runs in Tomcat as part of the webserver, and you have an accountinfo instance there. A second java process runs when you execute your test code. The only way your test java process can change the state of your Tomcat java process is by sending HTTP requests. If you call delete(accountName) in your test code, you will change the state of the accountinfo instance in your test java process, but this won't impact on the state of your Tomcat java process.
  3. Do I need to delete accounts after I add them? Yes, most definitely. Test cases should always restore the state of the system to what it was before they ran. That makes them repeatable, and reduces the chances for conflict with other test cases. You should investigate the setUp() and tearDown() methods in JUnit, which can facilitate this process.
> Dear Dr. Hacker,
>
> I am able to do the request.getParameter("username");
> but I could not do the request.setParameter("username", sjim);
>
> I have this error...
> testCreate Error No parameter named 'username' is defined in the form
> com.meterware.httpunit.NoSuchParameterException: No parameter named
> 'username' is defined in the form at
> com.meterware.httpunit.WebRequest.validateOneParameterValue(WebRequest.java:5 at
> com.meterware.httpunit.WebRequest.validateParameterValue(WebRequest.java:524)at
> com.meterware.httpunit.WebRequest.setParameter(WebRequest.java:69)
>
> I have spend 2 hours on this and I am going no where....
>
> -- Almost 1:00am and I'm still hacking
Dude, go to bed already and look at this again in the morning! This is a classic situation of needing to set it down and come back to it later with fresh eyes. In this case, the issue is quite clearly stated in the error message: "No parameter named 'username' is defined in the form..."

What's going on is that your httunit test is trying to find a parameter named "username" in the form that's in your jsp page, but you forget to define that parameter. You need to edit the jsp page and add a field called username to the form. The request object has nothing to do with the problem; that's just your fatigue getting in the way.

> Dr.Hacker,
>
> If both of team members did not update the program in cvs within several
> hours, one of team member update it since he/she did not know whether
> other team member update or not, what would happened?
>
> e.g.
> I committed the program this afternoon, tonight I updtaed the program from
> CVS since I was not sure my team member did some new work or not. but
> I saw some message from cvs like this. Do you know what is wrong with it?
>
> the last several lines look like as follow:
> ****************************************************************
> cvs server: Updating lib/Ant1.4.1/bin
> cvs server: Updating lib/Ant1.4.1/lib
> U lib/Ant1.4.1/lib/accountinfo.jar
> cvs [update aborted]: cannot rename file .new.accountinfo.jar to
> accountinfo.jar: File exists
> ***************************************************************
>
> -- Update me on this, please
You can invoke CVS update as many times as you want; nothing bad will happen if nothing has changed since the last time you invoked it. There is a definite rhythm to using CVS in a group context:

First, you invoke CVS update very frequently; at the very least before beginning work for the day and maybe more often than that.

Second, immediately after invoking CVS update, you build the new version of the system and run the test cases. That tells you if your updated system still compiles and runs. If it doesn't, then one of your group members has "broken the build".

Third, you don't commit files into the system unless the resulting system compiles and runs all of the test cases successfully. Otherwise, you're breaking the build.

Fourth, you try to cut down the size of your additions and enhancements to things that can be accomplished and committed in a small number of minutes, hours, or at the outside, days.

In CSDL, we have a short page summarizing this approach:

http://csdl.ics.hawaii.edu/FAQ/cvs.html

Finally, there are times when CVS gets conflicts that it can't resolve, such as the problem with .new.accountinfo.jar and accountinfo.jar that you mention above. In this case, the easiest solution is to go into your workspace directory, delete accountinfo.jar (and .new.accountinfo.jar if it exists), and repeat your invocation of cvs update.

Cheers, Dr. Hacker

3/11/2002

Dear Readers,

In my intro to web applications, I commented in class that I have come to the conclusion that EJB is overkill for many web application contexts. I recently came across an article that makes the same claims and thought you guys might find it of interest:

http://www.newarchitectmag.com/archives/2001/12/serv/

> Dear Dr. Hacker,
> 
> I'm sorry to tell you we took up so many spaces from your CVS server.
> 
> There are five modules like "sdunan-rxue-***********" in your CVS.
> They are (1)"sdunan-rxue-accountinfo",
>          (2)"sdunan-rxue-accountinfo2",
>          (3)"sdunan-rxue-accountinfo3",
> 
>          (4)"sdunan-rxue-accountinfomvc",
>          (5)"sdunan-rxue-accountinfomvc1".
> 
> (1) has different structure from others. But we met problem in (3) and
> (4). They work well in my local machine. The problem is I can not commit
> *.jpx in these two modules succesfully. I tried it several times but they
> still keep red color even the message indicates it success. They are
> not new files. I also tried other ways such as deleting them first and add
> again. But it failed. So Sally can not get updated *.jpx and *.java from
> CVS. One classmate said she also has some problems like some files always
> keep red color. But she is lucky. Her group member can get the updated
> version after she deleted the local module.
> 
> So we create two new modules to keep on working. They are (2) and (5).
> 
> The possible reason is maybe because we didn't close JBuilder when we
> imported the module. Maybe Jbuilder put a lock on it. We didn't set it
> as read only.
> The other bad thing we did is (3) and (4) are not clean versions.
> 
> - If at first you don't succeed, import another CVS module
Let me remind you of a few things and perhaps that will clear up the confusion:

(a) WinCVS makes a file "red" when it sees that the file mod time associated with the file in your local workspace differs from the file mod time associated with the (most recently downloaded) version in the CVS repository.

(b) JBuilder updates the .jpx file when things change in the project definition. These changes are saved somewhat unpredictably, but are always saved out when you exit JBuilder. If you commit the .jpx file while JBuilder is open, it is quite likely that JBuilder will write out the file again in the near future, causing WinCVS to report it as red (again). In addition, JBuilder writes your changes to the .java files when you do a compile (or save).

(c) WinCVS has been reported to fail to refresh after an update on *rare* occasions, which could result in a file being displayed as red even though it's in sync with the repository. If this happens, you can either refresh within WinCVS or restart WinCVS itself to fix it. (I don't recall this ever happening to me.)

(d) Remember that it is possible to delete files from the CVS repository. If you mistakenly import a module containing a few extra "junk" files or subdirectories, don't just import a second module. Instead, clean up the repository you have.

In summary:

- Until you understand what's going on better, exit JBuilder before committing changes to ensure that you're committing the latest versions of the .jpx and .java files. My guess is that you aren't really experiencing the refresh problem at all; you're just experiencing WinCVS, CVS, and JBuilder working exactly the way they are supposed to.

- If WinCVS reports a file as "red", and you really think it shouldn't be, do a refresh and/or restart WinCVS. If it's still red, then it's not a bug in CVS, it's a bug in your understanding of configuration management.

- Importing a brand new module in an attempt to fix these kinds of problems is wasting your time and katrina's disk space.

I know that all of you are still novices at working with the CVS client-server setup, and that some of it seems very mysterious, and that it's tempting to think the system is buggy or just stupid. However, having had experience with a few configuration management systems, I can tell you that at the end of the day, most of your issues with CVS will disappear as you gain insight into the fundamental model of configuration management using local workspaces and a global repository. Although conceptually it doesn't seem like a big deal, operationally it impacts on the way you work in many subtle ways, and those changes don't permeate your development habits overnight. The problems you're reporting and the way you tried to deal with them illustrates that. But that's fine; hopefully your experience has given you new insight.

This is not to say that there aren't real problems with CVS. Some things that continue to exasperate me after having used it for years include: (a) line ending management for cross-platform development, (b) case sensitivity, and (c) security. Subversion is supposed to fix all of these things.

> Dear Dr. Hacker,
>
> But when I commited the files again I closed all other windows except CVS.
> So maybe the real reason is because I did synchronize my local machine
> time with YATS but my group member didn't.  And I just found YATS is a 30
> days trial version. Do we have to use it every time when we use CVS?
> 
> -- Time is on my side
Well done! I forgot about client-server time synchronization (and the lack thereof) as a cause of this kind of problem. Yes, if your local client is not time synced with a network clock (and thus with the CVS server), then you can get the "persistent red" problem (or the "File modified in future" problem if you're out of sync the other direction.)

As I noted in my WinCVS lecture (Hint #7), you must synchronize your local machine with the CVS server. I supplied YATS-32 as an example shareware package, but you're right; it stops syncing after 30 days. That leaves you with at least the following three options:

1. You can pay for it ($15.95).

2. You can investigate other packages. Here's a link to a bunch of them, some of which are freeware: * http://idirect.tucows.com/sync95.html

3. You can set your local client's time clock by hand to within a second of an official net time clock. Of course, you have to keep doing this every few days to keep your client in sync. Here's one source:

* http://www.time.gov/

Cheers, Dr. Hacker

3.12.2002

Dear readers,

A student came in today with the following conundrum. He wants to use the JavaBean accessor syntax in the JSTL tag libs, such as:

$element.firstName

Where "$element" refers to a "Student" object.

The problem is that in order to use this syntax in the taglib, the object has to conform to JavaBean conventions. One of these conventions is the presence of a public no-arg constructor:

public Student () { ... }

The problem is that in this particular application, "Student" objects must be created with parameters to initialize the internal state, and so the no-arg constructor is made private to prevent objects from being created that aren't semantically valid.

Yikes! What's a poor hacker to do?

I have been aware of this software engineering dilemma for a while now, and today I found a path between the horns.

It turns out that although the JavaBean convention requires that such a no-arg constructor be declared, it doesn't actually invoke it! Therefore, the way to have your taglib cake and eat your data abstraction cookie too is to declare the public constructor, but have it throw an error if it ever gets invoked:

public Student() throws RuntimeException {
  throw new RuntimeException("Illegal invoke of Student no-arg constructor.");
}
This is a good but not perfect solution, since by declaring it private, we got the advantages of compile-time checking for illegal usage. Now, client code containing a call to the public constructor will compile, although if it gets executed at run-time you'll get an exception.
> Dear Dr.Hacker,
> 
> Let me ask a question about Test Class.
> 
> I know we are supposed to make Test class for each command class. However,
> is it better to create test method for a specific jsp page in a jsp test class
> or within command test class? I think I have to test the title and link
> of the welcome.jsp page, using something like WebLink class of httpunit.
> Or don't we need to check these?
> 
> -- Testing page by page
One of the JOSSE guidelines is that every page and link should be tested. So, yes, you need to use the WebLink class.

However, it's not the case that every page and link must have its own test class. You might test several pages and links in the course of testing a single command, for example.

> Dear Dr. Hacker,
> 
> We tried to have the current fields of an Account be present in the text
> field of the modify form, however we couldn't figure it out.  You mentioned a
> tag library that made this extremely easy, did you find out which one it was?
> Cause we are stuck.  We would like to add that functionality.
See: http://jakarta.apache.org/taglibs/doc/input-doc/intro.html
> 
> Also, we noticed that you do not use the iterator bean variable in stackmvc.
> You did this: request.setAttribute("stackIterator", stackModel.iterator());
> Why didn't you use the iterator bean variable from ClearStack?  We tried to
> do that, however we were unsuccessful for some reason.  So, we thought that
> there must be a reason why you didn't use it that case.  Is our assumption
> correct?
> 
I don't know exactly why you were unsuccessful, because it's certainly possible to redesign StackModel to have an iterator bean.

Basically, I did it differently in ClearStack and StackModel for pedagogical reasons: I wanted you to have working examples of both approaches. In these two cases, since only one attribute (the iterator) of the object (either a ClearStack or a StackModel) is needed in the JSP page, I don't see a compelling design advantage one way or another.

However, as I mentionned in class, as the number of attributes that you may want to access from a given object in the JSP increases, the design advantage tilts toward the Bean accessor capability of the standard taglib. (i.e. the ClearStack approach). This is because the programmer can simply make the object of interest available to the JSP page designer, who then can independently decide which attributes to display without any further changes on the Java code side.

Cheers, Dr. Hacker