[jsword-devel] Feature found

DM Smith dmsmith555 at yahoo.com
Fri May 21 10:47:41 MST 2004

This is the doc to which I referred.
I am not sure if it gives different info than the link you provided.

The big question is should we deliver the code with asserts turned on or 

Corollary: What is sufficient testing? Is testing with asserts on 
sufficient? Or do we need to test with asserts off as well?

If we deliver with asserts off then the path through the code is 
different. The question to ask is whether we care how the code behaves 
if the assertion would have failed?

One fundamental design point is that an assert should never be used for 
flow control. The developer needs to have explicit flow control as if 
the assert is not there. I think that this was the point of Sun saying 
that it is not just a concise way of saying if (condition) then error(). 
   It is *less* than that if assertions are compiled out. I agree with 
you that it should not be *more*.

I am of the opinion that when possible the program should not surprise 
the end user with bizarre behavior. I call this the "principle of least 

In your example you returned a bad label, which is a lot less surprising 
than the program just quitting. So I think what you have is good. And it 
follows Sun's guidelines as well.

Joe Walker wrote:
> DM Smith wrote:
>> Sun recommends in the tutorial for asserts that they are not used for 
>> precondition checks. The basic reason is that they can be compiled 
>> out. For a precondition they recommend either a cascading failure or 
>> an explicit check with an appropriate action. Interestingly, Sun even 
>> recommends throwing a RuntimeException (such as an array out of 
>> bounds) over an assertion.
> Hmmm.
> Is the doc this one:
> http://java.sun.com/developer/Books/javaprogramming/jdk14/javapch06.PDF
> in HTML -
> I'm not sure I agree with is doc.
> My understanding of asserts and the whole DBC thing was:
> 1. trap errors as soon as possible in development
> 2. struggle on if at all possible in live
> The archetypal example being a doubly linked-list where we could assert 
> (next.previous == this) frequently. In development you want to know 
> which method is breaking this invariant, so you want your debugger to 
> kick in as soon as some code breaks the invariant, so you can fix it. In 
> live, so long and the users doesn't do anything that traverses the 
> broken link, they won't suffer any problems so you want to limp on 
> without forcing a crash.
> If I'm right in this, then I don't understand Sun's recommendations:
> - Don’t use to enforce constraints on arguments to public methods
> - Don’t use to enforce public usage patterns or protocols
> Sun have a recommendation:
> - Don’t use as a shorthand for if (something) error();
> Which I agree with, but the document seems to disagree with their own 
> recommendation - just a few lines later:
> "An assertion is not *just* a concise way to say if (expression) then"
> (Emphasis mine)
> This implies that assert is more than the if (something) case, which it 
> isn't supposed to be at all!
> Sun seem to view preconditions that can be turned on or off as inherent 
> contract breakage between debug and live, but I'm tempted to define 
> doing anything that could cause an assert in debug as a violation of 
> contract in the first place - you are entering un-defined territory, 
> from here on in all contract promises are null and void[*].
> I think I'm staying truer to the original assert design (Bertrand 
> Meyer?) in taking this approach, but I wouldn't claim to be an expert.
> Joe.
> [*] How can something be null AND void?
> public void foo() { return null; } won't even compile!
>> Given that you have added the else clause to add the acronym as a 
>> label, you have made the code behave better if the action is null and 
>> the assert is compiled out.
>> Right now the jnlp is set to leave asserts in. Do we want the program 
>> to exit abruptly if a developer has not tested every label created 
>> created with this routine? I think having a bad label is better than 
>> the program ending abruptly.
>> Joe Walker wrote:
>>> I was going to say - option 2, but on reflection a file can be 
>>> modified before it's arrival on your computer, so you're right and 
>>> option 3 is better.
>>> Either solution would make me happy though.
>>> I have a check-in to fix missing resources for the passage selection 
>>> pane, and an experiment to make getAction() assert or default in the 
>>> absence of said resources. Crosswire appears to be down, so I can't 
>>> check-in or even CVS diff, but my recollection is that in 
>>> common/swing/ActionFactory I changed createJLabel to:
>>> /**
>>>  * Construct a JLabel from the Action.
>>>  * Only Action.NAME and Action.MNEMONIC_KEY are used.
>>>  * @param acronymn the internal name of the CWAction
>>>  * @return A label, asserting if missing resources or with default vals
>>>  */
>>> public JLabel createJLabel(String acronymn)
>>> {
>>>     Action action = getAction(acronymn);
>>>     assert action != null : "Missing resource: "+acronymn;
>>>     JLabel label = new JLabel();
>>>     if (action != null)
>>>     {
>>>         label.setText(action.getValue(Action.NAME).toString());
>>>         Integer mnemonic=(Integer)action.getValue(Action.MNEMONIC_KEY);
>>>         if (mnemonic != null)
>>>         {
>>>             label.setDisplayedMnemonic(mnemonic.intValue());
>>>         }
>>>     }
>>>     else
>>>     {
>>>         label.setText(acronymn);
>>>     }
>>>     return label;
>>> }
>>> (slightly edited to stop wordwrap)
>>> Does that make sense?
>>> Joe.
>>> DM Smith wrote:
>>>> I found a "feature" which I am working on fixing.
>>>> When the xsl is compiled for reuse, it works very well to check each 
>>>> time it is used to see if there is a change and recompile it when it 
>>>> does. The compilation is expensive so it is best for the user to 
>>>> compile it. And recompiling it when it changes allows a developer to 
>>>> bring up the application and test iterative changes to the xsl. It 
>>>> serves no advantage to a non-developer.
>>>> The problem is when the xsl is in a jar the NetUtil.getLastModified 
>>>> returns the current time and the net result is that the xsl is 
>>>> compiled every time it is used.
>>>> I see three possible solutions:
>>>> 1) return 0 when the resource is in a jar. This is the simplest 
>>>> solution. The problem with this is that if there is any persistence 
>>>> of a n artifact based upon that timestamp, then it will not see any 
>>>> changes.
>>>> 2) return the timestamp of the jar. So if there is persistence and 
>>>> the jar changes then it would force a recompile even if the xsl did 
>>>> not change. The basic thought is that the changes to the jar are 
>>>> going to be relatively infrequent and even recompiling the xsl once 
>>>> for each run of the application is not that big a deal.
>>>> 3) return the timestamp on the file in the jar. This is a complete 
>>>> solution and matches the expectation of the method's contract.
>>>> The form of the url that I am trying to work with is:
>>>> jar:file:/a/b/c/jarname.jar!/x/y/filename.ext
>>>> In this case I can pick off the file:.../jarname.jar and the 
>>>> .../filename.ext and use JarFile to get the JarEntry to interrogate.
>>>> The problem is that the solution is still not completely 
>>>> generalized. What if the jar's file is served up via ftp or http. I 
>>>> don't know what that url would look like. Would it be something like:
>>>> http:jar:file:.../jarname.jar!.../filename.ext.
>>>> I am inclined to do nothing for this situation.
>>>> On another note, I think Eclipse M9 is coming out later today. I 
>>>> have been using an integration build for the last week and it is 
>>>> better than M8.

More information about the jsword-devel mailing list