Loading ...
Sorry, an error occurred while loading the content.
 

Re: Asserts in Java

Expand Messages
  • Sean Higgins
    Rob Thanks for your comments. The nearest to zero-overhead asserts I ve found for java is a little messy, goes like this... ...in the Assert class public
    Message 1 of 6 , Oct 31, 2000
      Rob
      Thanks for your comments. The nearest to zero-overhead asserts I've found
      for java is a little messy, goes like this...

      ...in the Assert class
      public static final boolean ON = false; // change to true to enable asserts

      ...in the code, write each assert like this
      if (Assert.ON) Assert.check(condition,"optional text to show on failure");
      ...or...
      if (Assert.ON && Assert.check(condition,text));

      As I understand it, the constant Assert.ON is evaluated at compile time
      and the whole if statement results in zero code when ON = false.

      Downside is you need Just One Little Source Change to flip from development
      to production build, leading to some kind of source control /configuration
      / build environment kludge to do it automagically.

      Upside is its the nearest thing to C's zero-overhead-in-production.

      If you (or anyone out there) knows a better way I'd love to hear it.
      Requirements are :
      (1) zero overhead in production,
      (2) stop-dead-with-a-stacktrace when tripped in development
      (3) no changes to source using asserts in changing from dev to prod
      (4) if possible, no source changes at all - do it by some external input to
      the build process.

      Sean

      At 11:36 AM 31/10/00 -0800, you wrote:
      >>May I remind y'all that asserts are totally free of runtime
      >>penalty - in the release build. By the time they are disabled
      >>(by a compile-time switch)
      >
      >So, what option to javac disables assertions (which aren't part of the
      >language, which has no ifdef-like capability)?
      >
      >I've seen assertions done in Java with low run-time penalty (instead of
      >passing a boolean, pass an object that has a method that returns a
      >boolean, have the Assertion class go into low-overhead mode via a
      >Property setting), but not zero. It gets ugly to code those if you
      >assert different, complex conditions with any frequency. You could do
      >it with build environment hacking, but that gets pretty ugly.
      >
      >Personally, I like having assertions, even in my Java code, even with
      >the run-time penalty. I've even left them on in production systems.
      >These days I am writing low-level libraries for embedded devices and my
      >precondition on most methods is "true" with error handling defined for
      >all cases that don't make semantic sense. The performance requirements
      >really do leave me requiring zero run-time influence and I find the
      >code and build environment that would be required for that to be
      >unacceptable. This means I don't have postconditions, loop invariants
      >(or loop variants), but still have class invariants that I check
      >occasionally.
      >
      >Regards,
      >
      >Rob
      >
      >
      >=====
      >Please note: use email address sartin@... for address books.
      >
      >
      >__________________________________________________
      >Do You Yahoo!?
      >Yahoo! Messenger - Talk while you surf! It's FREE.
      >http://im.yahoo.com/
      >
      >
    • Laurent Bossavit
      ... Use a preprocessor. One which doesn t actually extend the language but overloads comment syntax a la Javadoc. Rationale : even the static-final-boolean
      Message 2 of 6 , Oct 31, 2000
        > If you (or anyone out there) knows a better way I'd love to hear it.
        > Requirements are :
        > (1) zero overhead in production,
        > (2) stop-dead-with-a-stacktrace when tripped in development
        > (3) no changes to source using asserts in changing from dev to prod
        > (4) if possible, no source changes at all - do it by some external input to
        > the build process.

        Use a preprocessor. One which doesn't actually extend the language
        but overloads comment syntax a la Javadoc.

        Rationale : even the static-final-boolean trick doesn't have *zero*
        overhead - it carries a cost in development. The slightly higher
        overhead, coding-wise, of a preprocessor just might pay for itself in
        time saved writing longer asserts to take advantage of boolean
        evaluation semantics. The overhead (CPU-wise) in production code is
        nil - it is simply compiled with straight javac or jikes, to which
        comments are just comments.

        Lastly, there is a communication advantage; compare :
        if (Assert.ON) Assert.check(condition,"optional text on failure");
        and
        //YouFuckedUp: "optional text" unless: condition


        -[Morendil]-
        .siht gnidaer emit ruoy etsaw t'noD
      • Jim Little
        From: Sean Higgins [ways of doing asserts] ... to ... Why do you have requirement #1? Seriously: Is there a space issue? Have you proven
        Message 3 of 6 , Oct 31, 2000
          From: "Sean Higgins" <seanh@...>
          [ways of doing asserts]
          > If you (or anyone out there) knows a better way I'd love to hear it.
          > Requirements are :
          > (1) zero overhead in production,
          > (2) stop-dead-with-a-stacktrace when tripped in development
          > (3) no changes to source using asserts in changing from dev to prod
          > (4) if possible, no source changes at all - do it by some external input
          to
          > the build process.

          Why do you have requirement #1? Seriously:

          Is there a space issue? Have you proven that asserts take up too much
          space?
          Is there a performance issue? Have you proven that asserts take too much
          time?

          Have you considered that bugs exist in deployed code, too, and that asserts
          are the easiest way to find those bugs? I hate trying to reproduce customer
          problems, but it's a lot easier if I have a stack trace.

          Have you considered that disabling asserts can introduce bugs? Example:

          String sql = "select count(*) from foo";
          ResultSet resultSet = statement.query(sql);
          Assert.isTrue("always one row", resultSet.next());
          return resultSet.getInteger(1);

          This exact bug showed up in a code review once. For those of you who don't
          get it, JDBC is a horrid little beast, and ResultSet.next() has a
          side-effect that causes the code to fail if it isn't called... which it
          wouldn't be, if asserts were disabled.

          Jim
        • Robert Sartin
          ... Well, the context we were discussing (off-list email) was developing software in Java for protocol processing on embedded devices. There is a major space
          Message 4 of 6 , Nov 1 8:42 AM
            > > Requirements are :
            > > (1) zero overhead in production,
            > Why do you have requirement #1? Seriously:

            Well, the context we were discussing (off-list email) was developing
            software in Java for protocol processing on embedded devices. There is
            a major space issue. I have customers arguing about 21K vs. 20K class
            files. There is a time issue, but it largely involves customer saying
            "has to be as fast as possible". However, looking at the reasonable
            assertions to write, they would be fairly expensive to test (in a
            couple of examples, the assertions were over an order of magnitude more
            expensive to test than the code they protected). Most importantly, we
            have an environment that won't handle the exceptions well (device soft
            resets in many cases).

            My resolution of that has been to mostly code methods with precondition
            "true" and limit use of postconditions, loop invariants, loop variants,
            and other intermediate invariants. Class invariants can be checked
            periodically and we have a logging mechanism for violations that occur
            there.

            > Have you considered that bugs exist in deployed code, too, and that
            > asserts are the easiest way to find those bugs?

            I sometimes agree with that assertion :-). In the context I was
            discussing, I don't.

            > Have you considered that disabling asserts can introduce bugs?
            > Example:

            The example is a fundamentally broken assertion. Assertions should
            absolutely never have a side effect. Even a strategy that leaves
            assertions in the code, but dynamically decides whether to evaluate
            them could have serious problems with such bad code.

            Regards,

            Rob




            __________________________________________________
            Do You Yahoo!?
            From homework help to love advice, Yahoo! Experts has your answer.
            http://experts.yahoo.com/
          • Arrizza, John
            ... I agree with everything in your post! You might consider another issue with Assertions: they take up a finite amount of time even if they have no side
            Message 5 of 6 , Nov 1 8:51 AM
              > -----Original Message-----
              > From: Robert Sartin [mailto:sartin@...]
              > The example is a fundamentally broken assertion. Assertions should
              > absolutely never have a side effect.

              I agree with everything in your post!

              You might consider another issue with Assertions: they take up a finite
              amount of time even if they have no side effects. This means there is a
              difference in execution times between Debug and Release. If the difference
              is large enough then subtle race conditions may kick in. It is an unusual
              situation, but can cause a lot of head scratching when it does occur.

              There is no real solution to this problem but it pays to be aware of it.

              John
            • Sean Higgins
              Jim You raise valid points. My comments on each below like this SH From: Jim Little SH (1) zero overhead in production, JL Why do you
              Message 6 of 6 , Nov 1 12:42 PM
                Jim
                You raise valid points. My comments on each below like this SH>
                From: "Jim Little" <jiml@...>
                SH> (1) zero overhead in production,
                JL>Why do you have requirement #1?
                Is there a space issue?
                Have you proven that asserts take up too much
                space?
                Is there a performance issue?
                Have you proven that asserts take too much
                time?
                SH> Yes to all the above, but MAINLY because developers wont use asserts
                where they're most useful if it means ANY overhead at all. So to remove
                any objection to their use, the overhead must be absolute zero. Even with
                a *small* overhead, you will still find places where code must be as fast
                as possible, so the temptation is to skip the asserts there, at the cost
                of more difficult debugging. A thoroughly assert-equipped program runs
                considerably slower than its production equivalent.

                JL>Have you considered that bugs exist in deployed code, too?
                SH> despite all efforts to eliminate via UTs running with asserts enabled,
                yes.
                If its an unattended system it must recover/restart, and if it can log useful
                stuff all the better.

                JL>asserts are the easiest way to find those bugs?
                SH> no. You need something quite different to make an app able to survive
                and report its own bugs. Thats why asserts are best implemented as
                sudden-death,
                its TSTTCPW for bug-detection during development. Sudden death (with a
                terse assert-fail message) in a deployed app is a great way to infuriate
                users.
                must

                JL>Have you considered that disabling asserts can introduce bugs? <example
                snipped>
                SH>The example is a classic, thanks. It is of course a bug in the Assert
                statement itself, which masks another bug in the assert-free code. In
                your case it was caught by review. Unit tests would likely also catch it.
                Thats why asserts alone are not sufficient. It also reminds me that you
                should UT and FT the PRODUCTION build too.

                Sean
              Your message has been successfully submitted and would be delivered to recipients shortly.