<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>(\_ -&#62; Phil Varner) &#187; java</title>
	<atom:link href="http://www.philvarner.com/blog/category/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.philvarner.com/blog</link>
	<description>mostly technical stuff</description>
	<lastBuildDate>Sat, 06 Mar 2010 18:01:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Java is dead/alive</title>
		<link>http://www.philvarner.com/blog/2008/12/10/java-is-deadalive/</link>
		<comments>http://www.philvarner.com/blog/2008/12/10/java-is-deadalive/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 07:59:56 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.philvarner.com/blog/?p=67</guid>
		<description><![CDATA[Funniest thing I read today:
&#034;Autoboxing was a misguided effort to paper over Java’s early decision to have a segregated type system for primitives and objects. It was Java’s Plessy v. Ferguson decision that pretended primitives and objects were separate but equal; but the claim was no more true in Java than it was in American [...]]]></description>
			<content:encoded><![CDATA[<p>Funniest thing I read today:</p>
<blockquote><p>&#034;Autoboxing was a misguided effort to paper over Java’s early decision to have a segregated type system for primitives and objects. It was Java’s Plessy v. Ferguson decision that pretended primitives and objects were separate but equal; but the claim was no more true in Java than it was in American jurisprudence.&#034;</p></blockquote>
<p>I do love a good Supreme Court ruling analogy.  </p>
<p>From one of my favorites, Elliotte Rusty Harold, in <a href="http://cafe.elharo.com/programming/java-is-dead-long-live-python/">Java is Dead! Long Live Python!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.philvarner.com/blog/2008/12/10/java-is-deadalive/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Proleptic apoplexy</title>
		<link>http://www.philvarner.com/blog/2008/07/12/proleptic-apoplexy/</link>
		<comments>http://www.philvarner.com/blog/2008/07/12/proleptic-apoplexy/#comments</comments>
		<pubDate>Sat, 12 Jul 2008 08:17:23 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.philvarner.com/blog/?p=53</guid>
		<description><![CDATA[I spent a few hours this week trying to figure out why some date manipulation methods I was writing weren&#039;t working.  In my test case, I had two instances of GregorianCalendar which I was comparing, an original and one that had been round-tripped through some conversion methods, via oracle.jbo.doman.Timestamp.  Using the equals method, [...]]]></description>
			<content:encoded><![CDATA[<p>I spent a few hours this week trying to figure out why some date manipulation methods I was writing weren&#039;t working.  In my test case, I had two instances of GregorianCalendar which I was comparing, an original and one that had been round-tripped through some conversion methods, via oracle.jbo.doman.Timestamp.  Using the equals method, they were returning false.  I used the toString method to see if there was something obviously different, but the strings were exactly the same.  I even when so far as to step though equals in the debugger, until it disappeared into a JDK implementation class for which the source was unavailable.  Even stranger, I discovered using compareTo returned 0.  I set about printing each property of the instances until I discovered problem: the GregorianChange property.</p>
<p>In the tests, I was using XMLGregorianCalendar to take an ISO 8601 date string (e.g., 2006-09-22T00:00:00.000-00:00) and create a GregorianCalendar.  The intention of this was to allow users to create statements like &#034;if Order.timestamp > DateLib.from(&#034;2006-09-22T00:00:00.000-00:00&#034;), do something&#034;.  Below is the reduction of what was happening in the test and application code:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.GregorianCalendar</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.xml.datatype.DatatypeFactory</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CalTest <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #003399;">String</span> dtstring <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;2006-09-22T00:00:00.000-00:00&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #003399;">GregorianCalendar</span> gcFromXmlgc <span style="color: #339933;">=</span>
            DatatypeFactory.<span style="color: #006633;">newInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
                .<span style="color: #006633;">newXMLGregorianCalendar</span><span style="color: #009900;">&#40;</span>dtstring<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toGregorianCalendar</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003399;">GregorianCalendar</span> gcFromCons <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">GregorianCalendar</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        gcFromCons.<span style="color: #006633;">setTimeZone</span><span style="color: #009900;">&#40;</span>gcFromXmlgc.<span style="color: #006633;">getTimeZone</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        gcFromCons.<span style="color: #006633;">setTimeInMillis</span><span style="color: #009900;">&#40;</span>gcFromXmlgc.<span style="color: #006633;">getTimeInMillis</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;equals? &quot;</span> <span style="color: #339933;">+</span> gcFromXmlgc.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>gcFromCons<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;compareTo? &quot;</span> <span style="color: #339933;">+</span> gcFromXmlgc.<span style="color: #006633;">compareTo</span><span style="color: #009900;">&#40;</span>gcFromCons<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;XML GC: &quot;</span> <span style="color: #339933;">+</span> gcFromXmlgc.<span style="color: #006633;">getGregorianChange</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;new GC: &quot;</span> <span style="color: #339933;">+</span> gcFromCons.<span style="color: #006633;">getGregorianChange</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Running this produces the following output:</p>
<pre>
equals? false
compareTo? 0
XML GC: Sun Dec 02 08:47:04 PST 292269055
new GC: Thu Oct 04 16:00:00 PST 1582
</pre>
<p>equals is false, but compareTo is 0? That&#039;s curious.  The last two lines show why, now explained.</p>
<p>The core of the problem is <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/datatype/XMLGregorianCalendar.html">XMLGregorianCalendar</a> is intended to represent the <a href="http://www.w3.org/TR/xmlschema-2/">W3C XML Schema 1.0 date/time datatypes</a>.  The date/time type in XML Schema <a href="http://www.w3.org/TR/xmlschema-2/#isoformats">essentially implements ISO 8601</a>, with a few minor exceptions.  The important part here is that it represents a &#034;proleptic Gregorian calendar&#034;.  </p>
<p>The <a href="http://en.wikipedia.org/wiki/Gregorian_calendar">Gregorian calendar</a> is the calendar used exclusively in the West and by most of the global business world.  Most people in the West don&#039;t even know there&#039;s even a name for the calendar, they just know it as &#034;the calendar&#034;.  The Gregorian calendar was adopted in 1582 to correct for the gradual drift caused by the previous Julian calendar. This change set the nominal date back 10 days and added a more astronomically appropriate leap year rule.  The &#034;<a href="http://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar">proleptic</a>&#034; Gregorian calendar is then the Gregorian rules  applied to dates before the calendar was adopted, as if the calendar had always been in effect.  Therefore, all Western dates after 1582 are according to the Gregorian calendar, but any date before this can be in either the Julian calendar or the proleptic Gregorian calendar, with one always being  specified explicitly.</p>
<p>Knowing this, one would then assume that the class GregorianCalendar implemented a proleptic Gregorian calendar.  However, belying it&#039;s name, it actually represents a hybrid Julian-Gregorian, with each type having a set of rules as to the order of different dates, and the ability to set a date which defines when the rules cutover. The well-known <a href="http://joda-time.sourceforge.net/">Joda-Time</a> library names these correctly, with a proleptic Gregorian, a postleptic Julian, and a hybrid GregorianJulian. The JDK 1.5 documentation includes this description, but it&#039;s not really useful unless you know what the semantics behind it mean.  GregorianCalendar.toString() doesn&#039;t print it out, so you have to know it exists and to explicitly examine it when debugging.  For most code using dates, the cutover date doesn&#039;t matter, since most software isn&#039;t going to be used for dates in the distant past, and if it is, there&#039;s hopefully a domain expert on hand to specify this sort of thing. </p>
<p>A default instance of GregorianCalendar implements a non-proleptic calendar &#8212; dates before to 4 October 1582 are in Julian, dates after are Gregorian.  However, XMLGregorianCalendar implements a proleptic Gregorian calendar as specified by ISO 8601, so it sets the change date to Long.MIN_VALUE.  The Timestamp class uses millis since the epoch (1970), so it will always give us a representation of the same date, but not the same GregorianCalendar.  In Sun JDK 1.5, the only difference in equals between Calendar and GregorianCalendar is the change date:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"> <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> equals<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> obj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> obj <span style="color: #000000; font-weight: bold;">instanceof</span> <span style="color: #003399;">GregorianCalendar</span> <span style="color: #339933;">&amp;&amp;</span>
        <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>obj<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span>
            gregorianCutover <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">GregorianCalendar</span><span style="color: #009900;">&#41;</span>obj<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">gregorianCutover</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>GregorianCalendar inherits compareTo (implementing Comparable<T>) from Calendar, which simply compares the millis since the epoch.  GNU Classpath 0.18 has a different implementation, as it doesn&#039;t take into account the change date:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> equals<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> o<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span> <span style="color: #009900;">&#40;</span>o <span style="color: #000000; font-weight: bold;">instanceof</span> <span style="color: #003399;">GregorianCalendar</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003399;">GregorianCalendar</span> cal <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">GregorianCalendar</span><span style="color: #009900;">&#41;</span> o<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>cal.<span style="color: #006633;">getTimeInMillis</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> getTimeInMillis<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>In writing my tests, I have made a huge error&#8211; I was testing for object equality, when I should have been testing for value ordering.  I shouldn&#039;t have cared if the objects were the same, what I really cared about was that there was no distinguishable ordering between them&#8211; that both objects represented the same value.  </p>
<p>I didn&#039;t actually write the tests from scratch, I had actually translated them from other date tests written in Oracle Business Rules RL, which as semantics similar to Java, but not exactly.  The relevant difference here is that you can use the relative operators on Comparable implementors, which then are converted to calls to compareTo at runtime.  I made the mistake of regex-replacing a bunch of obj1 != obj2 to !obj1.equals(obj2), when I should have done obj1.compareTo(obj2) != 0.  If these had been any of the relative operators, I would have used compareTo, but != took me to !equals.  Big mistake.</p>
<p>I learned a lot from this distraction, not just about calendars, but more importantly about equals and compareTo.  I recently started reading the new version of Effective Java, so the sections on comparison and equality have new and deeper meaning for me now.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.philvarner.com/blog/2008/07/12/proleptic-apoplexy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TestNG, part 2</title>
		<link>http://www.philvarner.com/blog/2008/02/10/testng-part-2/</link>
		<comments>http://www.philvarner.com/blog/2008/02/10/testng-part-2/#comments</comments>
		<pubDate>Mon, 11 Feb 2008 05:27:30 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[testng]]></category>

		<guid isPermaLink="false">http://www.philvarner.com/blog/2008/02/10/testng-part-2/</guid>
		<description><![CDATA[Since migrating from JUnit 3, TestNG has been wonderful.  Groups are the killer feature of TestNG that really make it worth the migration cost.  When wanting to test a single method, I no longer need to manually comment or uncomment method names in the suite() method, I can just add a new group [...]]]></description>
			<content:encoded><![CDATA[<p>Since migrating from JUnit 3, TestNG has been wonderful.  Groups are the killer feature of TestNG that really make it worth the migration cost.  When wanting to test a single method, I no longer need to manually comment or uncomment method names in the suite() method, I can just add a new group and run it from the command-line (well, from Ant.  see below).  Annotation-based test methods are much nicer, and have a much lower risk of accidentally being left out of the suite.</p>
<p>Just a few caveats before I show the Ant/TestNG setup we&#039;re currently using.  </p>
<ul>
<li>Merely moving to a new framework exposed several unintended test dependencies, so tests then failed because they ran after other tests.  With the suite method, they always ran in the same order, so these dependencies were never found.  None of ours were important, but there could have been ones that masked bugs.</li>
<li>Only void methods with names starting with &#034;test&#034; are annotated with @Test.  This may seem obvious, but we had a few tests written by a developer auxiliary to our main team who had written a few tests that weren&#039;t prefixed properly, but ran because they were in the suite method. The JUnitConverter class should probably try and parse the suite method to find problems like this (Maybe I&#039;ll to a patch for this).</li>
<li>Only void returning methods annotated with @Test are run.  Having a test method return a value doesn&#039;t generally make sense (it didn&#039;t in this case, either), but it may be difficult to understand if you test isn&#039;t running even though it&#039;s annotated.</li>
</ul>
<p>Okay, so now onto the good stuff&#8211; our Ant/TestNG configuration.  In these examples, I&#039;ve replaced the name of my actual project with &#034;foobar&#034;, and the prefix &#034;sdk&#034; indicates that it&#039;s the SDK part of the project.</p>
<p>First, in our common.xml file that is imported by all of our individual build.xml files, I added these lines, to define the location of the jar, add it to the common classpath, define the Ant task, and define the location for the reports to go ($twork is set to a temporary directory for the build):</p>
<pre>
&lt;property name="testng.jar" value="${test.src.dir}/lib/testng-5.7-jdk15.jar" /
&gt;

&lt;path id="foobar.common.class.path"&gt;
  ....
  &lt;pathelement location="${test.src.dir}/lib/testng-5.7-jdk15.jar"/&gt;
  ....
&lt;/path&gt;

    &lt;taskdef name="testng" classpathref="foobar.common.class.path"
          classname="org.testng.TestNGAntTask" /&gt;

    &lt;property name="testng.report.dir" value="${twork}/testng-report" /&gt;
</pre>
<p>Then in the build.xml for the specific tests, I added these targets.  To clean, I added a target to delete old results:</p>
<pre>
    &lt;target name="clean"&gt;
        &lt;delete failonerror="false" quiet="false" includeemptydirs="true"&gt;
            &lt;fileset dir="${testng.report.dir}" includes="**/*"/&gt;
        &lt;/delete&gt;
    &lt;/target&gt;
</pre>
<p>Then I added a couple of targest to either produce a single &#034;suc&#034; (success) or &#034;dif&#034; (failure) file based on the results of the run (these files are used by the continuous build system to report the results of running the tests on a new build).</p>
<p><strong>UPDATE:</strong><a href="http://www.philvarner.com/blog/2008/12/11/double-derefer…nt-with-groovydouble-dereferenced-properties-in-ant-with-groovy/">See this post for an updated version of the following targets.</a></p>
<pre>
    &lt;target name="process-results" depends="copy-failure, copy-success" /&gt;

    &lt;target name="copy-failure" if="has.failure"&gt;
        &lt;copy file="${testng.report.dir}/testng-failed.xml"
                tofile="${T_WORK}/foobar.sdk.${infix}.dif"
                failonerror="false" overwrite="true" /&gt;
    &lt;/target&gt;

    &lt;target name="copy-success" if="has.success"&gt;
        &lt;copy file="${testng.report.dir}/testng-results.xml"
                tofile="${T_WORK}/foobar.sdk.${infix}.suc"
                failonerror="false" overwrite="true" /&gt;
    &lt;/target&gt;
</pre>
<p>Then, we have the target that actually calls the testng task.  This target is never called directly, only through helper targets.  Notice that it adds two listeners: one that will give use intermediate results on the command-line as the tests are running, and one that will give us a summary report at the end.  After running, it then calls the previously mentioned targets.  One thing I missed at first was that the test class files must be included in both the classpath (so the JVM can find them) and the classfileset element, so that TestNG will know what classes to use for the tests.</p>
<pre>
    &lt;target name="run-testng" depends="" &gt;
          &lt;property name="excluded-groups" value=""/&gt;
        &lt;testng groups="${groups}" outputDir="${testng.report.dir}"
listeners="foobar.test.sdk.TestListener,foobar.test.sdk.SDKReporter"
excludedgroups="${excluded-groups}" &gt;
            &lt;jvmarg value="-ea"/&gt; &lt;!-- enable assertions --&gt;
            &lt;classpath&gt;
                &lt;pathelement path="${twork.sdk}"/&gt;
                &lt;pathelement path="${foobar.common.class.path}"/&gt;
            &lt;/classpath&gt;
            &lt;classfileset dir="${twork.sdk}" includes="foobar/test/**/${t
estcase}.class"/&gt;
        &lt;/testng&gt;
        &lt;condition property="has.failure" value="true" &gt;
            &lt;available file="${testng.report.dir}/testng-failed.xml" /&gt;
        &lt;/condition&gt;

        &lt;condition property="has.success" value="true" &gt;
            &lt;available file="${testng.report.dir}/testng-results.xml" /&gt;
        &lt;/condition&gt;

        &lt;antcall target="process-results" &gt;
          &lt;param name="infix" value="${groups}"/&gt;
        &lt;/antcall&gt;

    &lt;/target&gt;
</pre>
<p>The next thing was to set up a few helper targets to call the run-testng target.  The first was &#034;run-testcase&#034;, which would allow you to run a group from only a specific TestCase class, for a feel similar to JUnit.  This is run with the command line &#039;ant run-testcase -Dgroups=srg -Dtestcase=BazTestCase&#039;.  Note that the group &#034;broken&#034; is excluded by default.  If you actually want to run the broken group, you call it with &#039;ant run-testcase -Dgroups=broken -Dtestcase=BazTestCase -Dexcluded-groups=&#034;"&#039; to populate the property exclude-groups so it&#039;s redefinition is ignored.  Also, we add the most used command-line target, rung.  This called with &#034;ant rung -Dgroups=srg&#034;, or more commonly when I&#039;m using it, &#034;ant rung -Dgroups=phil&#034;.  I can just add my name to the groups for a test case, and easily run only that one while debugging code or writing new tests.  This alone was worth the migration to TestNG&#8211; it&#039;s liberating when writing tests.  </p>
<pre>

    &lt;target name="run-testcase" depends="setup"&gt;
        &lt;property name="groups" value=""/&gt;
        &lt;property name="exclude" value="broken"/&gt;
        &lt;antcall target="run-testng"&gt;
          &lt;param name="testcase" value="${name}"/&gt;
          &lt;param name="groups" value="${groups}"/&gt;
          &lt;param name="excluded-groups" value="${exclude}"/&gt;
        &lt;/antcall&gt;
    &lt;/target&gt;

    &lt;target name="rung" depends="setup"&gt;
        &lt;antcall target="run-testng"&gt;
          &lt;param name="testcase" value="*"/&gt;
          &lt;param name="groups" value="${groups}"/&gt;
        &lt;/antcall&gt;
    &lt;/target&gt;
</pre>
<p>This is the listener that reports the intermediate results from running each test method.  The name of the test class has its front chopped off so most of them will fit in an 80 character column, and it also prints the count of the tests (to gauge how far progressed the tests are) and the run-time for each test (to help gauge if there are any high-runtime/low-value tests out there).  The one thing I would like to add but haven&#039;t looked at yet is printing out the actual results of the assert failure rather than just the stack trace of where it occured.  I currently just look in the HTML report at the end for this.</p>
<pre>

package foobar.test.sdk;

import org.testng.*;

public class TestListener extends TestListenerAdapter {
    private int m_count = 0;

    private String name(ITestResult tr){
        return tr.getTestClass().getName().replaceAll("foobar\\.test\\
.","") +
            "." + tr.getMethod().getMethodName();
    }

    @Override
    public void onTestFailure(ITestResult tr) {
        log("[FAILED " + (m_count++) + "] =&gt; " + name(tr) );
    }

    @Override
    public void onTestSkipped(ITestResult tr) {
        log("[SKIPPED " + (m_count++) + "] =&gt; " + name(tr) );
    }

    @Override
    public void onTestSuccess(ITestResult tr) {
        log("[" + (m_count++) + "] =&gt; "+ name(tr) + " " + (tr.getEndMillis()-t
r.getStartMillis()) + "ms");
    }

    private void log(String string) {
        System.out.println(string);
    }
}
</pre>
<p>This is the reporter that I use for the summary report at the end of running all the tests:</p>
<pre>
package foobar.test.sdk;

import org.testng.*;
import java.util.*;

import static java.util.Arrays.asList;

public class SDKReporter implements IReporter {

    private String name(ITestResult tr){
        return tr.getTestClass().getName() + "." + tr.getMethod().getMethodNam
e();
    }

    public void generateReport(List&lt;org.testng.xml.XmlSuite&gt; xmlsuites ,List&lt;o
rg.testng.ISuite&gt; suites,String c) {

        for (ISuite suite : suites){
            Map&lt;String,ISuiteResult&gt; results  = suite.getResults();
            for(Map.Entry&lt;String,ISuiteResult&gt; entry : results.entrySet()){
                ITestContext itc =   entry.getValue().getTestContext();
                for (ITestResult tr : itc.getFailedConfigurations().getAllResu
lts()){
                    log ("Failed Config: " + name(tr));
                    log (asList(tr.getThrowable().getStackTrace()));
                }

                for (ITestResult tr : itc.getFailedTests().getAllResults()){
                    log ("Failed Test: " + name(tr));
                    log (asList(tr.getThrowable().getStackTrace()));
                }

                for (ITestResult tr : itc.getSkippedConfigurations().getAllRes
ults()){
                    log ("Skipped Config: " + name(tr));
                    log (asList(tr.getThrowable().getStackTrace()));
                }

                for (ITestResult tr : itc.getSkippedTests().getAllResults()){
                    log ("Skipped Test: " + name(tr));
                    log (asList(tr.getThrowable().getStackTrace()));
                }

            }
        }
    }

    public void log(java.util.List&lt;java.lang.StackTraceElement&gt; trace){
        for (StackTraceElement ste : trace){
            String s = ste.toString();
            if (s.startsWith("sun.reflect.NativeMethodAccessorImpl")) {
                log("\n-------------------------------------\n");
                return ;
            }
            log("\t" + s);
        }
    }

    public void log(String s) {
        System.out.println(s);
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.philvarner.com/blog/2008/02/10/testng-part-2/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Shards in your Latte</title>
		<link>http://www.philvarner.com/blog/2008/01/20/shards-in-your-latte/</link>
		<comments>http://www.philvarner.com/blog/2008/01/20/shards-in-your-latte/#comments</comments>
		<pubDate>Sun, 20 Jan 2008 22:40:08 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[puzzles]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.philvarner.com/blog/2008/01/20/shards-in-your-latte/</guid>
		<description><![CDATA[Here are the slides from my &#034;Shards in your Latte&#034; PJUG presentation on January 15:
javasharpedges.pdf
The Josh Bloch / Bill Pugh puzzlers talk from JavaOne given at Google.  The Elvis example comes straight from here, and they do a better example of describing it than I did.
The Java Puzzlers book.
A couple of things that came [...]]]></description>
			<content:encoded><![CDATA[<p>Here are the slides from my &#034;Shards in your Latte&#034; PJUG presentation on January 15:</p>
<p><a href='http://www.philvarner.com/blog/wp-content/uploads/2008/01/javasharpedges.pdf' title='javasharpedges.pdf'>javasharpedges.pdf</a></p>
<p>The Josh Bloch / Bill Pugh <a href="http://tinyurl.com/2744gz">puzzlers talk</a> from JavaOne given at Google.  The Elvis example comes straight from here, and they do a better example of describing it than I did.</p>
<p>The <a href="http://tinyurl.com/33kyh7">Java Puzzlers book</a>.</p>
<p>A couple of things that came up at the talk:</p>
<ul>
<li>There&#039;s no version of String.replaceAll that takes a Pattern. I said I thought there was without thinking for more than a second about it.</li>
<li>Until the most recent version of Groovy, it didn&#039;t have a classical C-style &#039;for&#039; loop.  There was a lot of disagreement when I mentioned it, and I should have been more precise when I said that as to not imply that Groovy had no &#039;for&#039; loop constructs.</li>
</ul>
<p>Please add anything you think I got wrong, or anything you found interesting.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.philvarner.com/blog/2008/01/20/shards-in-your-latte/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bubble, bubble, toil and Double</title>
		<link>http://www.philvarner.com/blog/2007/12/08/bubble-bubble-toil-and-double/</link>
		<comments>http://www.philvarner.com/blog/2007/12/08/bubble-bubble-toil-and-double/#comments</comments>
		<pubDate>Sat, 08 Dec 2007 18:41:37 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[puzzles]]></category>

		<guid isPermaLink="false">http://www.philvarner.com/blog/?p=26</guid>
		<description><![CDATA[Inspired by Weiqi Gao&#039;s Friday Java Quiz this week, I came up with a few more curiosities of Java double.  What do each of the calls to larger() print?  Hint: this puzzle has nothing to do with type conversion loss of precision, it is only about the specified behavior of doubles.

public class Foo [...]]]></description>
			<content:encoded><![CDATA[<p>Inspired by Weiqi Gao&#039;s <a href="http://www.weiqigao.com/blog/2007/12/07/friday_java_quiz_know_your_java_lang_classes.html">Friday Java Quiz</a> this week, I came up with a few more curiosities of Java double.  What do each of the calls to larger() print?  Hint: this puzzle has nothing to do with type conversion loss of precision, it is only about the specified behavior of doubles.</p>
<pre>
public class Foo {
    public static void main(String[] args) {
        larger(0.0d, Double.MIN_VALUE);
        larger(1.0d, Double.MIN_VALUE*Double.MAX_VALUE);
        larger(1.0d, Double.MIN_VALUE*Double.MAX_VALUE*Double.MAX_VALUE);
        larger(1.0d/Double.MIN_VALUE, 1.0d/(1.0d/Double.MAX_VALUE));
        larger(1.0d/Double.MIN_VALUE, 1.0d/0.0d);
        larger(1.0d, Double.MIN_VALUE/Double.MIN_VALUE);
    }

    public static void larger(Double a, Double b){
        System.out.print(a + " or " + b + " ? ");
        if (a < b){
        System.out.println(b);
        } else if (a > b){
        System.out.println(a);
        } else {
        System.out.println("equal");
        }
    }
}
</pre>
<p>Highlight the hidden text below for the answers:<br />
<font color="white"><br />
0.0 or 4.9E-324 ? 4.9E-324<br />
1.0 or 8.881784197001251E-16 ? 1.0<br />
1.0 or 1.5966722476277755E293 ? 1.5966722476277755E293<br />
Infinity or Infinity ? equal<br />
Infinity or Infinity ? equal<br />
1.0 or 1.0 ? equal<br />
</font></p>
]]></content:encoded>
			<wfw:commentRss>http://www.philvarner.com/blog/2007/12/08/bubble-bubble-toil-and-double/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>String Theory</title>
		<link>http://www.philvarner.com/blog/2007/12/02/string-theory/</link>
		<comments>http://www.philvarner.com/blog/2007/12/02/string-theory/#comments</comments>
		<pubDate>Mon, 03 Dec 2007 04:32:41 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.philvarner.com/blog/?p=24</guid>
		<description><![CDATA[No, not that string theory.  This string theory is testable.   In fact, the moral of this story is this: don&#039;t make any assumptions about Java.  The compiler or the VM.  They do crazy stuff, like make your code run better.  If you think you have an inefficiency in your [...]]]></description>
			<content:encoded><![CDATA[<p>No, not that string theory.  This string theory is testable.   In fact, the moral of this story is this: don&#039;t make any assumptions about Java.  The compiler or the VM.  They do crazy stuff, like make your code run better.  If you think you have an inefficiency in your code, test it to see.  It could be that you&#039;re about to make your code less readable for no performance benefit.  </p>
<p>The software I do at work has a code generation component, so there&#039;s a bunch of string concatenation and output.  The main path for generation passes around a StringBuilder (which is 20% faster than the old synchronized StringBuilder) to multiple classes, which each concatenate code into it.  Some of the code generation within each class still used string concatenation (+=) for building intermediate strings, and I knew we needed to convert it to use an SB.  When I ran FindBugs on the codebase, this alone accounted for about 25% of the true positives.  </p>
<p>The main uses in the code are things like:</p>
<pre>
String s = "";
for (Foo f: foos){
    s += "baz " + f.id + " { " + f.type + " } ";
}
</pre>
<p>or </p>
<pre>
StringBuilder sb = ...;
for (Foo f: foos){
    sb.append("baz " + f.id + " { " + f.type + " } ");
}
</pre>
<p>My original thought was that both of these were horrible and were creating <em>n</em> strings in memory for each concat, which where then immediately thrown away.  However, after doing a few experiments and looking at the bytecode, I discovered a few things.  First, the compiler converts Strings concat&#039;ed using &#039;+&#039; into calls to StringBuilder.append.  This means that there aren&#039;t any intermediate String objects generated in a call like &#034;a+b+c&#034;, only a StringBuilder and the result String.  The first snippet above is still bad, because to create new String to assign to <em>s</em>, it has to create two new immutable Strings, one with the value of the String to add and one with the result of the concat.  The garbage collector then must clean up the SB, the String from the SB, and the old value of <em>s</em>.  In the second snippet, the only intermediate objects that gets thrown away is a StringBuilder, but all of it&#039;s state is reused by the StringBuilder we keep.  As the numbers below show, there&#039;s not that much difference between multiple chained calls to append and one call to append with the syntactic sugar of the &#039;+&#039;.  Using the &#039;+&#039; syntax is much more readable, so this is the option I&#039;m going with in my code.</p>
<p>The trivial moral for the story is never to use &#039;+=&#039;, but using + inside an append is fine.  The general moral is that from now on, I&#039;m definitely going to measure, then change. </p>
<p>The results for various String concat methods:</p>
<table border="1">
<tr>
<th align="center">#</th>
<th align="center">test</th>
<th align="center">code</th>
<th align="center">server (ms)</th>
<th align="center">client (ms)</th>
<th align="center">notes</th>
</tr>
<tr>
<td align="right">1</td>
<td align="left">string + w/ vars</td>
<td align="left">s += a + b + c</td>
<td align="right">929</td>
<td align="right">2388</td>
<td align="left"></td>
</tr>
<tr>
<td align="right">2</td>
<td align="left">string + w/ consts</td>
<td align="left">s += &#034;a&#034; + &#034;b&#034; + &#034;c&#034;</td>
<td align="right">902</td>
<td align="right">2380</td>
<td align="left">the compiler transforms this into &#039;s += &#034;abc&#034;&#039;</td>
</tr>
<tr>
<td align="right">3</td>
<td align="left">string + w/ SB</td>
<td align="left">s += new StringBuilder().append(a)<br />
.append(b).append(c).toString()</td>
<td align="right">915</td>
<td align="right">2390</td>
<td align="left">like bytecode of (1)</td>
</tr>
<tr>
<td align="right">4</td>
<td align="left">str bld + </td>
<td align="left">sb.append(a + b + c)</td>
<td align="right">9</td>
<td align="right">14</td>
<td align="left">common pattern</td>
</tr>
<tr>
<td align="right">5</td>
<td align="left">str bld + CTC </td>
<td align="left">sb.append(&#034;a&#034; + &#034;b&#034; + &#034;c&#034;)</td>
</td>
<td align="right">7</td>
<td align="right">11</td>
<td align="left">constants instead of variables (4)</td>
</tr>
<tr>
<td align="right">6</td>
<td align="left">str bld ++ </td>
<td align="left">sb.append(new StringBuilder()<br />
.append(a).append(b)<br />
.append(c).toString())</td>
<td align="right">9</td>
<td align="right">14</td>
<td align="left">bytecode of (4)</td>
</tr>
<tr>
<td align="right">7</td>
<td align="left">str bld app	 </td>
<td align="left">sb.append(a).append(b).append(c)</td>
</td>
<td align="right">7</td>
<td align="right">11</td>
<td align="left">most &#039;proper&#039; usage</td>
</tr>
<tr>
<td align="right">8</td>
<td align="left">MString append </td>
<td align="left">sb.append(a,b,c)</td>
<td align="right">8</td>
<td align="right">12</td>
<td align="left">impl. of &#034;faster&#034; interface</td>
</tr>
</table>
<p>This is the example code for the tests.  Note that closures would have been really useful here, since I wouldn&#039;t have had to duplicate this method (can&#039;t wait for 7!).</p>
<pre>
    public long runStringBuilderAppend(){
        long start = System.currentTimeMillis();
        try {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < runs; i++){
                sb.append(a).append(b).append(c);
            }
            sb.toString();
            sb = null;
        } finally {
            if (gc) System.gc();
            return (System.currentTimeMillis() - start);
        }
    }
</pre>
<p>source: <a href='http://www.philvarner.com/blog/wp-content/uploads/2007/12/StringTest.java' title='StringTest'>StringTest.java</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.philvarner.com/blog/2007/12/02/string-theory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
