tag:blogger.com,1999:blog-96209482024-03-06T18:34:20.164-08:00Binstock on SoftwareThoughts on Software and ProgrammingAndrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.comBlogger110125tag:blogger.com,1999:blog-9620948.post-1744156908264065572024-02-26T23:38:00.000-08:002024-03-06T18:33:48.915-08:00Jacobin JVM at 30 Months<p><span style="font-family: inherit;">This month, the <a href="http://www.jacobin.org">Jacobin JVM project</a> reaches the 30-month milestone, with release 0.4.0. Because for the last six months Richard Elkins (<a href="https://github.com/texadactyl">@texadactyl</a>) and I have been working together daily on features, we've made good progress. Our goal is before year-end to have it run a standard <a href="https://benchmarksgame-team.pages.debian.net/benchmarksgame/">set of benchmarks</a>. After that, we'll begin to ask for volunteers to test Jacobin with their code. As ever, the larger goal is to deliver a more-than-minimal JVM written entirely in a single language (go).</span></p><p><span style="font-family: inherit;">To be honest, Jacobin is already much more than minimal, but we want to get it closer to feature parity with the HotSpot JVM, which is the JVM that ships in OpenJDK. During the past six months, we've added:</span></p><p><span style="font-family: inherit;">* </span><b style="font-family: inherit;">exception handling, both caught and uncaught exceptions</b><span style="font-family: inherit;"> and errors. For uncaught errors, we try to provide somewhat more detail about the exception than does the HotSpot JVM. However, for users who prefer HotSpot's exact wording, we provide the </span><span style="font-family: Consolas;">-strictJDK</span><span style="font-family: inherit;"> command-line option, which uses the exact same wording as HotSpot. </span></p><p><span style="font-family: inherit;">* <b>improved diagnostic data in trace logs</b>. Prior to this release, out trace logs were focused on the bytecode instructions, showing the class, method, bytecode and the top of the operand stack (TOS). We now print out the entire operand stack with each bytecode instruction so that we can watch data items move up and down the stack as pushes and pops move them. While this generates huge trace listings, it lets us watch the execution of classes in a real-time document. </span></p><p><span style="font-family: inherit;">* <b>handling methods with a variable number of arguments</b></span></p><p><span style="font-family: inherit;"><span>* </span><b style="font-family: inherit;">static initializer blocks</b><span>. Initiatlizer blocks are rarely used by developers, but crucial to the operation of the JVM. At the language level, they're blocks of code between </span><span style="font-family: Consolas;">{{</span><span> and </span><span style="font-family: Consolas;">}}</span><span> or in freestanding blocks of code between marked </span><span><span style="font-family: Consolas;">static{</span><span style="font-family: inherit;"> ...code here... </span><span style="font-family: Consolas;">}</span><span style="font-family: inherit;">. They're most often used to initialize static variables. The code blocks are executed before any code in a class, even before a constructor. Inside the JVM, they appear when classes use static variables, which means frequently. And they can entail complex chain reactions in which they need to instantiate other classes and run their static initializer blocks. </span></span><b><br /></b><br />* <b>revised architecture</b>. One of the confounding aspects of working on a system with so many discrete subsystems that must all interoperate in a carefully choreographed process is that it's difficult to anticipate the exact shape and interfaces a subsystem must have when it's first designed. In part, that's because we generally cannot implement all the features right away--only the essential ones. Gradually, as Jacobin moves forward, earlier decisions to not include certain lesser-used features need to be revised. In this release, we revised how we look up methods and how we handle static variables. In both cases, we simplified existing code. </span></p><h3 style="text-align: left;"><span style="font-family: inherit;">Hacker News</span></h3><p><span style="font-family: inherit;">Jacobin JVM made the <a href="https://news.ycombinator.com/item?id=37247394">front page of Hacker News</a>. That post by <a href="https://github.com/yelinaung">Ye Lin Aug</a>, generated 184 interesting comments. We appreciated this unexpected coverage and did our best to answer the many questions. <br /></span></p><h3 style="text-align: left;"><span style="font-family: inherit;">What's next</span></h3><p></p><p><span style="font-family: inherit;">In the next six month sprint, we are hopeful that we can:</span></p><p><span style="font-family: inherit;">* implement all remaining bytecodes except INVOKEDYNAMIC, which will surely take us longer to complete</span></p><p><span style="font-family: inherit;">* implement </span><span style="font-family: Consolas;">java.lang.Class</span><span style="font-family: inherit;">: there are several Java classes that are so dependent on the JVM's design that every JVM needs to implement them by hand. These include classes for threads, debugging classes, and, of course, java.lang.Class...among others.</span></p><p><span style="font-family: inherit;">* add file I/O libraries (it might seem odd to see this here, but the JDK's file I/O libraries are native functions. We need to implement then in go. This will primarily be via use of the Facade design pattern, but there will likely be some additional coding required.)</span></p><p><span style="font-family: inherit;">* expanded work on handling JAR files. Presently Jacobin <i>does</i> handle JAR files. However, we want to make sure that code is robust enough to handle all details and forms of JAR files, so that execution never fails.<br /><br />All of this in preparation for running benchmark suites and, eventually, soliciting alpha testers.</span></p><p><span style="font-family: inherit;">In the above text, I've referred to this milestone as a "release." The term is misleading. We're not creating a release, but just marking the code at this 2.5-year anniversary as v. 0.4.0. As discussed on the GitHub project site, we don't yet recommend you try Jacobin. However, by the end of the next sprint, we hope to start inviting folks to give it a try. <br /><br /></span></p><h3 style="text-align: left;"><span style="font-family: inherit;">Testing</span></h3><p></p><p><span style="font-family: inherit;">As discussed in previous posts, we're deeply committed to testing. Jacobin's test suites currently run a total of 708 tests, which include 597 unit tests and 111 integration tests. We'll be boosting these number significantly in preparation for inviting alpha testers. <br /><br /></span></p><h3 style="text-align: left;"><span style="font-family: inherit;">Jacobin by the Numbers</span></h3><p><span style="font-family: inherit;">At present, Jacobin consists of a production codebase of 15,814 lines (includes code, comments, and blank lines). The testing code consists of 24,178 lines plus 26,874 lines in the Jacotest test suite. This gives 50,912 lines of tests, which is 3.22x the size of the production code. Our eventual goal is a significantly greater multiple. </span></p><p><span style="font-family: inherit;">If you'd like to show your support for Jacobin JVM, we'd love a ⭐ on GitHub. That helps keep our motivation high! If you want more frequent updates, please follow us on Twitter (<a href="https://twitter.com/jacobin_jvm">@jacobin_jvm</a>)</span></p><p><span style="font-family: inherit;"><br /></span></p>Andrew Binstockhttp://www.blogger.com/profile/02636845733967051523noreply@blogger.com0tag:blogger.com,1999:blog-9620948.post-88191964120543051572023-08-09T13:02:00.001-07:002023-08-09T13:02:58.174-07:00Jacobin at the 2-year Mark<p><a href="https://jacobin.org/" target="_blank">Jacobin</a> (a JVM written entirely in Go) just reached its 2-year anniversary. Since our 18-month <a href="http://binstock.blogspot.com/2023/02/jacobin-jvm-at-18-months.html">update</a>, a lot has happened. We have:</p><p></p><ul style="text-align: left;"><li>Added instantiation of non-static classes</li><li>Added support for superclasses</li><li>Implemented the JDK’s native math libraries in Go</li><li>Added support for multidimensional arrays</li><li>Added support for compact strings</li><li>The interpreter now handles 190 bytecodes (out of 203)</li><li>Default to using the classes and libraries bunded with the OpenJDK</li><li>Significant instruction-level tracing capabilities (see below)</li></ul><p></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0in; mso-add-space: auto;"><span lang="EN-US" style="mso-ansi-language: EN-US;">What we’re working on now and taking
up shortly:<o:p></o:p></span></p><p class="MsoListParagraphCxSpMiddle" style="margin-left: 0in; mso-add-space: auto;"></p><ul style="text-align: left;"><li><span lang="EN-US" style="mso-ansi-language: EN-US;">Making sure that our test suites generate the same results as the OpenJDK JVM</span></li><li><span lang="EN-US" style="mso-ansi-language: EN-US;">Adding
the final bytecodes to the interpreter. (Some of these are <i>very</i> complicated, so
they will likely take a while.)</span></li><li><span lang="EN-US" style="mso-ansi-language: EN-US;">Add
exception handling</span></li><li><span lang="EN-US">Add
support for interfaces</span></li></ul><p></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-ansi-language: EN-US;">Even before
these goals are attained, we expect that to start running benchmarks and third-party
test suites on Jacobin. <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-ansi-language: EN-US;">Much of the
good progress we’ve made since our 18-month <a href="http://binstock.blogspot.com/2023/02/jacobin-jvm-at-18-months.html" target="_blank">update</a> is due to the
addition of Richard Elkins (<a href="https://github.com/texadactyl" target="_blank">@texadactyl</a>) to the team. He implemented the JDK’s native
math libraries and has created a test suite, <a href="https://github.com/texadactyl/jacotest.go">Jacotest</a>, which grinds on existing
and upcoming features. <o:p></o:p></span></p>
<p class="MsoNormal"><b><span lang="EN-US" style="mso-ansi-language: EN-US;">Tracing
and Peering into the JVM<o:p></o:p></span></b></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-ansi-language: EN-US;">Our progress
remains very much aligned with the original goals for Jacobin: a JVM capable of
running Java17 programs, written entirely in Go with no dependencies, delivered
as a small executable from a cohesive, extensively commented codebase. <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-ansi-language: EN-US;">At present,
Jacobin is a 3.9MB executable that is tested daily on Windows, Linux, and
MacOS. Because it’s a single codebase, we have the pleasure of loading it into
our IDE (<a href="https://www.jetbrains.com/go/" target="_blank">GoLand</a>, kindly provided by JetBrains) and stepping through the execution
of a class bytecode-by-bytecode following the execution path across classes and
libraries. <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-ansi-language: EN-US;">To give us
a roadmap, we expanded our already detailed instruction tracing to show the
values on the operand stack and other useful details. Here is a sample of the
tracing log (available by specifying the <span style="font-family: Consolas;">-trace:inst</span> option on the command line):<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: Consolas; font-size: 8.0pt; line-height: 107%; mso-ansi-language: EN-US;"><span style="mso-spacerun: yes;">
</span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span lang="EN-US" style="font-family: Consolas; font-size: 8.0pt; mso-ansi-language: EN-US;">java/lang/StringLatin1 meth:
inflate<span style="mso-spacerun: yes;"> </span>PC:<span style="mso-spacerun: yes;"> </span>30, GOTO<span style="mso-spacerun: yes;"> </span>TOS:<span style="mso-spacerun: yes;">
</span>-<span style="mso-spacerun: yes;"> </span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span lang="EN-US" style="font-family: Consolas; font-size: 8.0pt; mso-ansi-language: EN-US;">java/lang/StringLatin1 meth:
inflate<span style="mso-spacerun: yes;"> </span>PC:<span style="mso-spacerun: yes;"> </span>3, ILOAD<span style="mso-spacerun: yes;"> </span>TOS:<span style="mso-spacerun: yes;">
</span>-<span style="mso-spacerun: yes;"> </span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span lang="EN-US" style="font-family: Consolas; font-size: 8.0pt; mso-ansi-language: EN-US;">java/lang/StringLatin1 meth:
inflate<span style="mso-spacerun: yes;"> </span>PC:<span style="mso-spacerun: yes;"> </span>5, ILOAD<span style="mso-spacerun: yes;"> </span>TOS:<span style="mso-spacerun: yes;">
</span>0 int64 22<span style="mso-spacerun: yes;"> </span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span lang="EN-US" style="font-family: Consolas; font-size: 8.0pt; mso-ansi-language: EN-US;">java/lang/StringLatin1 meth:
inflate<span style="mso-spacerun: yes;"> </span>PC:<span style="mso-spacerun: yes;"> </span>7, IF_ICMPGE<span style="mso-spacerun: yes;"> </span>TOS:<span style="mso-spacerun: yes;">
</span>1 int64 22<span style="mso-spacerun: yes;"> </span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span lang="EN-US" style="font-family: Consolas; font-size: 8.0pt; mso-ansi-language: EN-US;">java/lang/StringLatin1 meth:
inflate<span style="mso-spacerun: yes;"> </span>PC:<span style="mso-spacerun: yes;"> </span>33, RETURN<span style="mso-spacerun: yes;"> </span>TOS:<span style="mso-spacerun: yes;">
</span>-<span style="mso-spacerun: yes;"> </span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span lang="EN-US" style="font-family: Consolas; font-size: 8.0pt; mso-ansi-language: EN-US;">java/lang/StringLatin1 meth:
toChars<span style="mso-spacerun: yes;"> </span>PC:<span style="mso-spacerun: yes;"> </span>14, ALOAD_1<span style="mso-spacerun: yes;"> </span>TOS:<span style="mso-spacerun: yes;">
</span>-<span style="mso-spacerun: yes;"> </span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span lang="EN-US" style="font-family: Consolas; font-size: 8.0pt; mso-ansi-language: EN-US;">java/lang/StringLatin1 meth:
toChars<span style="mso-spacerun: yes;"> </span>PC:<span style="mso-spacerun: yes;"> </span>15, ARETURN<span style="mso-spacerun: yes;"> </span>TOS:<span style="mso-spacerun: yes;">
</span>0 Object<span style="mso-spacerun: yes;"> </span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span lang="EN-US" style="font-family: Consolas; font-size: 8.0pt; mso-ansi-language: EN-US;">java/lang/String<span style="mso-spacerun: yes;"> </span>meth: toCharArray PC: 14, GOTO<span style="mso-spacerun: yes;"> </span>TOS:<span style="mso-spacerun: yes;">
</span>0 Object<span style="mso-spacerun: yes;"> </span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span lang="EN-US" style="font-family: Consolas; font-size: 8.0pt; mso-ansi-language: EN-US;">java/lang/String<span style="mso-spacerun: yes;"> </span>meth: toCharArray PC: 24, ARETURN<span style="mso-spacerun: yes;"> </span>TOS:<span style="mso-spacerun: yes;">
</span>0 Object<span style="mso-spacerun: yes;"> </span><o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span lang="EN-US" style="font-family: Consolas; font-size: 8.0pt; mso-ansi-language: EN-US;">main<span style="mso-spacerun: yes;"> </span>meth: main<span style="mso-spacerun: yes;"> </span>PC:<span style="mso-spacerun: yes;">
</span>41, ASTORE<span style="mso-spacerun: yes;"> </span>TOS:<span style="mso-spacerun: yes;"> </span>0 Object: &{{68288800 0} <nil> [{[I
0xc000004450}]}<o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in; text-align: left;"><span lang="EN-US" style="font-family: Consolas; font-size: 8.0pt; mso-ansi-language: EN-US;">main<span style="mso-spacerun: yes;"> </span>meth: main<span style="mso-spacerun: yes;"> </span>PC:<span style="mso-spacerun: yes;">
</span>43, GETSTATIC<span style="mso-spacerun: yes;"> </span>TOS:<span style="mso-spacerun: yes;"> </span>-<span style="mso-spacerun: yes;"> </span><o:p></o:p></span></p>
<p class="MsoNormal"><b><span lang="EN-US" style="mso-ansi-language: EN-US;"><o:p> </o:p></span></b></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-ansi-language: EN-US;">(Some
entries removed for simplicity.) In this listing, you see on the extreme left, the class name, the method name, the
program counter (</span><span lang="EN-US" style="font-family: Consolas; mso-ansi-language: EN-US;">PC</span><span lang="EN-US" style="mso-ansi-language: EN-US;">, which is the number of the bytecode being executed), the bytecode, and
the value on the top of the stack (</span><span lang="EN-US" style="font-family: Consolas; mso-ansi-language: EN-US;">TOS</span><span lang="EN-US" style="mso-ansi-language: EN-US;">). In this, </span><span lang="EN-US" style="font-family: Consolas; mso-ansi-language: EN-US;">TOS: 0</span><span lang="EN-US" style="mso-ansi-language: EN-US;"> means there is one item on the stack (at position 0) and its type and
value are shown immediately to the right (or on the next line in case of line wrapping).<span style="mso-spacerun: yes;"> </span><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-ansi-language: EN-US;">Notice that
in this excerpt, execution starts in </span><span lang="EN-US" style="font-family: Consolas; mso-ansi-language: EN-US;">java.lang.StringLatin1/inflate()</span><span lang="EN-US" style="mso-ansi-language: EN-US;">, eventually returns to the calling
function in </span><span lang="EN-US" style="font-family: Consolas; mso-ansi-language: EN-US;">java.lang.String</span><span lang="EN-US" style="mso-ansi-language: EN-US;">,
</span><span lang="EN-US" style="font-family: Consolas; mso-ansi-language: EN-US;">toCharArray()</span><span lang="EN-US" style="mso-ansi-language: EN-US;">. When this completes, it returns to
the </span><span lang="EN-US" style="font-family: Consolas; mso-ansi-language: EN-US;">main</span><span lang="EN-US" style="mso-ansi-language: EN-US;"> method in the class called </span><span lang="EN-US" style="font-family: Consolas; mso-ansi-language: EN-US;">main</span><span lang="EN-US" style="mso-ansi-language: EN-US;">. which is loaded with a pointer to an object that consists of an array of integers (in this particular case, an array of chars that form a string)<o:p></o:p></span></p>
<p class="MsoNormal"><b><span lang="EN-US" style="mso-ansi-language: EN-US;">Testing <o:p></o:p></span></b></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-ansi-language: EN-US;">As stated
in our previous posts, we’re deeply committed to testing. Currently, Jacobin uses a testbed of 618 tests: 525 unit tests and additional
93 tests in the Jacotest suite. Even at this level, we’re not satisfied with
the depth of coverage, and we expect to continue expanding the testing
aggressively.<o:p></o:p></span></p>
<p class="MsoNormal"><b><span lang="EN-US" style="mso-ansi-language: EN-US;">By the
Numbers<o:p></o:p></span></b></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-ansi-language: EN-US;">Jacobin
consists of 11,097 lines (this includes code, comments, and blank lines). The
525 unit tests represent 21,465 lines. The Jacotest suite consists of and
additional 21,921 lines (mostly Java). This totals to 43,386 lines of
testing code, which means our test code is currently 3.91x the size of our production
code. We aim to increase that ratio as we move forward.<o:p></o:p></span></p>
<p class="MsoNormal"><b><span lang="EN-US" style="mso-ansi-language: EN-US;">So,
where do we stand?<o:p></o:p></span></b></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-ansi-language: EN-US;">We’re not quite ready for users to
begin testing Jacobin. In this coming year, we aim to ship a release that you can
try out and test with your own Java classes. At that point, we’ll pivot to
improving performance. (If you want to jump the gun, though, you can always
download the code and do a build. Instructions on the <a href="https://github.com/platypusguy/jacobin/releases" target="_blank">release page</a>.)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-ansi-language: EN-US;">If you want
to help the project, we’d love a star on <a href="https://github.com/platypusguy/jacobin" target="_blank">GitHub</a> (this helps keeps our motivation
high) and perhaps let others know about the project. <o:p></o:p></span></p>Andrew Binstockhttp://www.blogger.com/profile/02636845733967051523noreply@blogger.com0tag:blogger.com,1999:blog-9620948.post-32215427312760372492023-02-14T13:53:00.000-08:002023-02-28T18:28:25.302-08:00Jacobin JVM at 18 months<p>Earlier this month, the Jacobin JVM project (a JVM written in Go) reached its 18-month milestone. Since our post at the 12-month mark, we have added support for numerous Java bytecodes to the interpreter, including all the bytecodes for longs, floats, doubles and their operations, all the bit manipulations, and all operations on single-dimensional arrays of primitives. We've implemented 176 bytecodes at present and expect to finish up the remaining ones we need during the coming six months.</p><p>At present, Jacobin can execute simple static classes, which is enough to allow us to test functionality and to begin running benchmarks. While performance has not in any way been a goal during our work, as we get closer to finishing the interpreter, it will assume greater importance. <a href="https://twitter.com/suresk" target="_blank">@suresk</a> is already sketching out an observability client, similar to VisualVM and other tools, to guide our optimization work. </p><p>Jacobin continues to meet our initial goals: it is written entirely in Go and has no dependencies. It runs fast and the executable is only 3.1MB (on Windows). It runs Java class files and JARs compiled by Java 7 through Java 17.</p><p><b>By the numbers</b></p><p>Jacobin's codebase consists of 25,813 lines (which include code, comments, and blank lines). As mentioned in earlier posts, we have a very deep commitment to testing as shown by the fact that this codebase includes 18,015 lines of testing code for the 7,798 of production code. This is a ratio of testing code to production code of 2.31x -- our highest to date (as we set out to do in earlier posts). Those 18K lines represent 429 unit and integration tests.</p><p class="MsoNormal" style="background-color: white; color: #333333; font-family: "Trebuchet MS", Verdana, Arial, sans-serif; font-size: 12.61px;"><b>Easy Things You Can Do to Help<o:p></o:p></b></p><p class="MsoNormal" style="background-color: white; color: #333333; font-family: "Trebuchet MS", Verdana, Arial, sans-serif; font-size: 12.61px;">While Jacobin is still in pre-alpha mode, if you choose to build it or run one of the posted executables on GitHub, we’d love your feedback. We respond quickly to any and all feedback and questions. In this regard, Richard Elkins (<a href="https://twitter.com/texadactyl" target="_blank">@texadactyl</a>) deserves our heartfelt thanks for running Jacobin on various test files and sharing his results with us.</p><p class="MsoNormal" style="background-color: white; color: #333333; font-family: "Trebuchet MS", Verdana, Arial, sans-serif; font-size: 12.61px;">If you’d just like to show your support for the project, we'd love a star on GitHub. Knowing people are interested in Jacobin really helps keep our motivation and spirits high. If you're on Twitter, please follow our handle (<a href="https://twitter.com/jacobin_jvm" style="color: #225588;">@jacobin_jvm</a>) to keep abreast of what we’re doing.</p><p><br /></p><p><br /></p>Andrew Binstockhttp://www.blogger.com/profile/02636845733967051523noreply@blogger.com0tag:blogger.com,1999:blog-9620948.post-48944670889312200172022-08-09T22:26:00.004-07:002022-08-09T22:26:41.300-07:00Jacobin JVM At The 1-year Mark<p> After 12 months, Jacobin, the more than minimalist JVM
written in Go, has come quite far. Presently, it can execute simple Java
classes and JARs and can do several interesting things, described shortly. The
source code, which is available under the Mozilla open source licence and <a href="https://github.com/platypusguy/jacobin" target="_blank">housed on GitHub</a>, contains several sample
Java classes that demonstrate the kinds of classes Jacobin can execute
accurately and quickly.</p><p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">Jacobin responds to most of the options listed in <span style="font-family: Consolas; font-size: 10.0pt; line-height: 107%; mso-bidi-font-family: "Cascadia Mono";">java -help</span>, including supporting a range of verbosity
options that can log considerable data to the console as the program is
running. For a huge amount of output, use <span style="color: #24292f; font-family: Consolas; font-size: 10.0pt; line-height: 107%;">-verbose:finest</span>
switch. You can even do <i>instruction-level tracing</i> with the <span style="color: #24292f; font-family: Consolas; font-size: 10.0pt; line-height: 107%;">-trace:inst</span>
command-line switch.<o:p></o:p></p>
<p class="MsoNormal">Jacobin is a single executable with no dependencies. It
requires only a JDK distribution on the local machine. Any JDK through Java 17
will work. <o:p></o:p></p>
<p class="MsoNormal">Under the covers, Jacobin—like OpenJDK-based JVMs—loads some
1,400 classes in the background. These comprise all the basic classes of the
Java distribution. The class loaders in Jacobin perform a detailed parse and
format-check of the app classes, with linking and preparation done on-the-fly
at execution time. <o:p></o:p></p>
<p class="MsoNormal"><b>What’s Next?<o:p></o:p></b></p>
<p class="MsoNormal">The team of Spencer Uresk (<a href="https://twitter.com/suresk">@suresk</a>) and Andrew Binstock
(<a href="https://github.com/platypusguy">@platypusguy</a>) are working primarily in the following areas: completion of the
bytecode interpreter (mostly to be completed by Andrew) and designing and
developing an observability client, mostly by Spencer. (Observability is the
ability to see what’s happening inside the JVM.) The <a href="https://github.com/platypusguy/jacobin/blob/main/README.md" target="_blank">README page</a> on GitHub gives the current status of the various subsystems under development. <o:p></o:p></p>
<p class="MsoNormal"><b>By the Numbers<o:p></o:p></b></p>
<p class="MsoNormal">After one year, the Jacobin codebase consists of 21,051
lines (including comments and blank lines). Of those, 14,499 lines make up 291 tests,
meaning that the testing code is presently 2.21x the size of the production
code. We strive to increase that multiple. The unit tests cover 72% of the
production code, while the integration tests cover even more. <o:p></o:p></p>
<p class="MsoNormal">This deep commitment to testing is crucial to advancing the
project. To move beyond running just the simplest of classes, Jacobin must
adopt a lot of the inner complexity of the JVM. Debugging the interactions of
many interlocking parts is nobody’s idea of fun. So, for our own peace of mind,
we invest heavily in making sure that the code we write works exactly as we
expect. And, of course, this also leads to a good user experience.<o:p></o:p></p>
<p class="MsoNormal"><b>Easy Things You Can Do to Help<o:p></o:p></b></p>
<p class="MsoNormal">While Jacobin is still in pre-alpha mode, if you choose to
build it or run one of the posted executables on GitHub, we’d love your
feedback. We respond quickly to any and all feedback and questions. If, instead,
you’d just like to show your support for the project, we'd love a star on
GitHub. Knowing people are interested in Jacobin really helps keep our
motivation and spirits high. If you're on Twitter, please follow our handle
(<a href="https://twitter.com/jacobin_jvm">@jacobin_jvm</a>) to keep abreast of what we’re doing. <o:p></o:p></p>
<p class="MsoNormal">Thank you for your interest. Onward to year 2!</p>Andrew Binstockhttp://www.blogger.com/profile/02636845733967051523noreply@blogger.com0tag:blogger.com,1999:blog-9620948.post-67913116494333577522022-05-08T21:25:00.004-07:002022-05-08T21:25:21.816-07:00Jacobin JVM project after nine months<p>After nine months, Jacobin has been steadily moving forward. The biggest news of this quarter is that Spencer Uresk (<a href="https://twitter.com/suresk" target="_blank">@suresk</a> on Twitter and <a href="https://github.com/suresk" target="_blank">suresk</a> on GitHub) has joined the project. He's made his presence felt right away by rewriting how Jacobin loads JDK classes at start-up. Previously, we provided a curated set of JDK classes in the Jacobin distribution. These classes were searched for in the directory specified by <span style="font-family: courier;">JACOBIN_HOME</span>. Spencer's improvement is that the classes are now loaded directly from the Java distribution on the runtime system. This means that if your system already has a JDK installed on it, all you need to run Jacobin is the single Jacobin executable file. Spencer has now turned his attention to running JAR files (because at present, Jacobin runs only individual class files).</p><p>While Spencer's working on that, I (Andrew Binstock) am continuing the work on the bytecode interpreter. Work is slow but steady and I aim to have it mostly complete by the end of this three-month cycle.</p><p>As of this quarter, we are compatible with classes through Java 17 (previously only through Java 11). We don't enforce sealed classes (Java 17's big new feature) but we can execute our test classes from Java 17 just fine.</p><h2 style="text-align: left;">By the numbers</h2><p>Project size has risen from 17,588 lines in our codebase to 19,173, which consists of 6,383 lines of production code and 12,970 lines in 248 tests--a 2.003x ratio of test code to production code. We'll look to increase that ratio as we move forward. (It was at 1.4x at the three-month mark, and 2.10x at the six-month mark.)</p><h3 style="text-align: left;">How you can help</h3><p>If you're interested in this project and you're on Github, we'd love a star. Knowing people are interested in Jacobin really helps keep our motivation and spirits high. If you're on Twitter, follow our handle (<a href="https://twitter.com/jacobin_jvm" target="_blank">@jacobin_jvm</a>). Thanks for your interest and support!</p>Andrew Binstockhttp://www.blogger.com/profile/02636845733967051523noreply@blogger.com0tag:blogger.com,1999:blog-9620948.post-43991342658720889942022-02-04T12:49:00.001-08:002022-02-04T12:49:28.599-08:00Jacobin JVM project after six months<p>After six months, Jacobin can now execute many of the most common bytecode instructions. Simple classes that use for-loops, call methods that compute values, and print the results to the screen work correctly. Several of these are now available in the <a href="https://github.com/platypusguy/jacobin/tree/main/testdata" target="_blank">testdata directory on GitHub</a>. For example, Hello3.class performs the following:</p><div style="text-align: left;"><span style="font-family: courier; font-size: x-small;">public static void main( String[] args) {<br /><span style="white-space: pre;"> </span>int x;<br /><span style="white-space: pre;"> </span>for( int i = 0; i < 10; i++) {<br /><span style="white-space: pre;"> </span> x = addTwo(i, i-1);<br /><span style="white-space: pre;"> </span> System.out.println( x );<br /><span style="white-space: pre;"> </span>}<br /> }<br /><br /></span></div><div style="text-align: left;"><span style="font-family: courier; font-size: x-small;"> static int addTwo(int j, int k) {<br /><span style="white-space: pre;"> </span>int m = multTwo(j, k);<br /><span style="white-space: pre;"> </span>return m+1;<br /> }<br /><br /></span></div><div style="text-align: left;"><span style="font-family: courier; font-size: x-small;"> static int multTwo(int m, int n){<br /><span style="white-space: pre;"> </span>return m*n;<br /> }<br />}</span></div><p style="text-align: left;">What you're seeing is a loop that calls a method, which in turn calls another method. If you run this without any command-line options, it will print out the expected result (a series of integers ranging from 1 to 73). </p><p style="text-align: left;">If you run it with <span style="font-family: courier; font-size: x-small;">-verbose:finest</span>, Jacobin will present a wealth of information about what's going on inside the JVM. You can also do instruction-level tracing with <span style="font-family: courier; font-size: x-small;">-trace:inst</span>. The last few lines of the instruction trace look like this:</p><div style="text-align: left;"><span style="font-family: courier; font-size: xx-small;">class: Hello3, meth: main, pc: 20, inst: INVOKEVIRTUAL, tos: 1<br />class: Hello3, meth: main, pc: 23, inst: IINC, tos: -1<br />class: Hello3, meth: main, pc: 26, inst: GOTO, tos: -1<br />class: Hello3, meth: main, pc: 2, inst: ILOAD_2, tos: -1<br />class: Hello3, meth: main, pc: 3, inst: BIPUSH, tos: 0<br />class: Hello3, meth: main, pc: 5, inst: IF_ICMPGE, tos: 1<br />class: Hello3, meth: main, pc: 29, inst: RETURN, tos: -1</span></div><p>The class and method fields are self-explanatory. <span style="font-family: courier;">pc</span> refers to the location of the bytecode instruction, <span style="font-family: courier;">inst:</span> refers to the actual instruction, and <span style="font-family: courier;">tos:</span> represents the top of the operand stack before the instruction (-1 = empty stack, 0 = 1 item on the stack, etc.)</p><p>When you run Jacobin, it loads some 1500 Java classes in the background (just like the JVM does). If you want to see the list of these classes, run Jacobin with the <span style="font-family: courier; font-size: x-small;">-verbose:class</span> command-line option. (A tribute to both the go language implementation and the design of Java classes is that these 1500 classes can be read, parsed, and posted in less than 300ms.) </p><h3 style="text-align: left;"><b>Current work</b></h3><p>We're presently working on object creation. (So far, all the test classes don't require the creation of new objects.) The next step will then be handling exceptions, and then running classes that are in separate source files. As we create test classes for these developments, we'll perforce be adding new bytecode instructions to our interpreter. </p><h4 style="text-align: left;"><b>By the numbers</b></h4><p>As of February 1 (six months into the project) the project spans 52 files consisting of 17,588 lines. Our pipeline consists of 223 tests and 11,922 lines (code and data) making our testing corpus 2.10x the size of our production code. We'll be looking to increase this ratio going forward. (It was 1.4x at the three-month mark.)</p><h3 style="text-align: left;"><b>How you can help</b></h3><p>If you're interested in this project and you're on Github, we'd love <a href="https://github.com/platypusguy/jacobin" target="_blank">a star</a>. Knowing people are interested in Jacobin really helps keep our motivation and spirits high. If you're on Twitter, follow our handle (<a href="https://twitter.com/jacobin_jvm" target="_blank">@jacobin_jvm</a>). Thanks for your interest and support!</p><p><br /></p><p><br /></p>Andrew Binstockhttp://www.blogger.com/profile/02636845733967051523noreply@blogger.com1tag:blogger.com,1999:blog-9620948.post-46602590751355490292021-12-17T14:42:00.000-08:002021-12-17T14:51:18.503-08:00How the Jacobin JVM Accesses Methods<p style="text-align: left;">Executing methods is the principal activity of the JVM. There are many steps involved in finding, loading, executing methods correctly. The <a href="https://github.com/platypusguy/jacobin/" target="_blank">Jacobin JVM</a> uses a variety of techniques to accelerate this process as described here. (To follow, you need to know just a little Java.) </p><h3 style="text-align: left;">Methods in class files</h3><p>Java methods are stored in class files in a section where various kinds of class attributes are located. Each method contains instructions in the form of Java bytecodes. It also contains a series of attributes that provide additional execution information (such as data for handling exceptions, debugging info, etc.) Functions are stored by name and type, which are represented by indexes into an area of the class file called the constant pool. Those indexes ultimately point to strings in UTF-8 format (actually, a Java-specific variant of UTF-8). A typical example looks like this:</p><p><span style="font-family: courier;">java/io/PrintStream.println:(I)V</span></p><p>This shows the usual <span style="font-family: courier;">println()</span> method that prints an integer to the console. Note that the name of the class precedes the method name. The class name has transformed the usual <span style="font-family: courier;">.</span> into forward slashes. The single dot demarks the method name, which is followed by a colon and the method signature. The part in parentheses indicates the parameter type (<span style="font-family: courier;">I</span>=integer) and the V after the closing parenthesis indicates the return value, which here is void (<span style="font-family: courier;">V</span>=void). Note to Java nerds: the signature of a method typically does not include the return value. It's specified here so that the JVM knows what to expect as a return value.</p><h3 style="text-align: left;">Extracting methods for use by the JVM</h3><p>The classloader is a JVM subsystem that locates classes needed by the application, parses them, and places (or loads) the parsed data into an important area of the JVM called the <i>method area</i>. The method area, despite its name, holds entire classes. When an app requires a method, it looks into the method area and determines whether the class has been loaded. If not, it asks the classloader subsystem to locate and load the class into the method area. Once the class is there, the JVM looks through all the method, resolves the name and signature strings for each of the methods and sees whether they match the method being looked for. When a match is found, the bytecodes are loaded and executed. (If the method is not found, a runtime error results.)</p><p>This search can be extremely expensive. For example, the Java standard <span style="font-family: courier;">Class.class</span> in Java 11 has 139 methods--that's potentially a lot of look-ups! To save time, most JVMs, including Jacobin, cache the method data once it's been looked up, so that the search is performed only once.</p><h3 style="text-align: left;">The Method Table</h3><p>In Jacobin, the caching is done using a <i>method table</i> (see file <a href="https://github.com/platypusguy/jacobin/blob/main/src/classloader/mTable.go" target="_blank">MTable.go</a>). When a method is invoked, Jacobin (like many JVMs), first checks the method table to see whether the method has previously been located and loaded. If not, then the search as described previously is performed. In Jacobin, the method is located and stored in the method table and then the look-up in the table is performed a second time and the result passed to the calling method. </p><h3 style="text-align: left;">Additional Considerations</h3><p><b>Thread safety</b>: The method table, like the method area, is a JVM-wide data structure. That is, all executing threads in the JVM can access it. As a result, it's conceivable that two threads would be updating the method table simultaneously. To avoid this problem, the table uses a mutex lock on every update. </p><p><b>Performance</b>: While developing the many capabilities of a JVM, Jacobin is aiming for acceptable performance. Eventually, though we'll be working very hard to maximize performance. Some of the techniques we have in our notebooks for future enhancements (some of which are used in other JVMs):</p><p></p><ul style="text-align: left;"><li>For the<span style="font-family: courier;"> main()</span> class and other classes that might appear in the same JAR, loading the methods directly into the method table, rather than waiting for the initial method search to load them. </li><li>When a method is loaded into the method table, deleting it from the class entry in the method area. There is no need to have the same data in memory twice. Doing this, reduces the memory footprint of the JVM.</li><li>When a class's methods are searched for a match (that is, prior to an entry in the method table), if no match is found in the class, then the superclass must be checked. If that fails, then that super-class's superclass is checked and so on up the chain until java.lang.Object is reached at the top of the object hierarchy. A simple optimization is to give every loaded class a complete list of all the superclass methods with pointers to them, so that the JVM does not have to climb the hierarchy in its search, but can tell quickly whether the method exists or not. </li></ul><p></p><p>There are surely other optimizations and refinements, which we hope to explore and to include if they lead to better execution.</p><p><br /></p><p><br /></p>Andrew Binstockhttp://www.blogger.com/profile/02636845733967051523noreply@blogger.com0tag:blogger.com,1999:blog-9620948.post-91839938455530539932021-11-02T18:41:00.004-07:002021-11-02T20:49:18.138-07:00Jacobin JVM project after three months<div style="text-align: left;"><span style="font-family: georgia;">Development on <a href="http://www.jacobin.org">Jacobin</a>, the JVM written in go that supports Java 11, has been proceeding rapidly. In the 100 days since the beginning of the project, there have been 314 pushed commits. I'll give more stats below. Here's where we stand:</span></div><div style="text-align: left;"><span style="font-family: georgia;"><br />Jacobin can read, parse, format check, and load class files. This process happens very quickly. For example, running all these steps on one of the largest classes in the JDK distribution, <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/BigDecimal.html">BigDecimal.class</a>, takes just 2ms. When parsed, BigDecimal has 1567 entries in its constant pool, 37 fields, and 167 methods. That's a huge class! </span></div><div style="text-align: left;"><span style="font-family: georgia;"><br />When a class is loaded by Jacobin or any other JVM, it necessarily pulls in other classes to be loaded. For example, all classes run from the command-line have a superclass. Often, that superclass is <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html" target="_blank">java.lang.Object</a>, which depends on other classes. Among these are <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Class.html" target="_blank">java.lang.Class</a> and <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html" target="_blank">java.lang.String</a>; various I/O classes are needed as well. The OpenJDK-based JVMs (essentially, all JVMs except IBM's J9 and some embeddable VMs) address this need by preloading hundreds of widely used classes at JVM start-up. For a look at the list of all the classes loaded just to display the JVM version info, run this from the command line:</span></div><p><span style="font-family: courier;"><b>java -verbose:class -version</b></span><br /><br /><span style="font-family: georgia;">On my Java 11 test system, this command preloads 381 classes (in 347ms!) While Jacobin does not need as many classes loaded to run the specified class, it needs a subset of them. The next step in the project is to identify the required classes and load them quickly. To this end, loading opertions (parsing and format checking) will need to be done in parallel. Fortunately, one of the go language's strengths is a rich set of easy-to-use resources for precisely this kind of concurrent operation.</span></p><p><span style="font-family: georgia;">After this task is completed, work will begin on execution. </span></p><h2 style="text-align: left;"><span style="font-family: georgia;">Testing Thoroughly</span></h2><p></p><div style="text-align: left;"><span style="font-family: georgia;">One of the principal goals of Jacobin is to be a reliable JVM. This requires disciplined work in the planning, development, and testing. Development is based entirely in tasks which are logged in a cloud-instance of JetBrains' excellent tool, <a href="https://www.jetbrains.com/youtrack/" target="_blank">YouTrack</a> (graciously provide for free). You can see the presence of this tracking, in that every commit on GitHub starts with the corresponding task name. (Presently, the most recent task is</span> <span style="font-family: courier;"><b>JACOBIN-89</b></span>.)<span style="font-family: georgia;"> Quality of the code is reviewed by automatic linters on GitHub. Currently, the code merits an A+. The goreport badge on the <a href="https://github.com/platypusguy/jacobin" target="_blank">jacobin GitHub project</a>, takes you to <a href="https://goreportcard.com/report/github.com/platypusguy/jacobin" target="_blank">the most recent report</a>.</span></div><span style="font-family: georgia;"><br /></span><div style="text-align: left;"><span style="font-family: georgia;">Testing is done on a <i>near-fanatical</i> basis. Let me explain:</span></div><div style="text-align: left;"><span style="font-family: georgia;"><br />In 2005, I was a contractor with Agitar, a now-shuttered company that made a tool which would read a Java codebase and generate unit tests for missing areas of coverage. It worked great. In conversations with their sales engineers, they told me they used a back-of-the-envelope calculation to assess a company's commitment to testing. They compared the size of the test codebase to the production code. If the test codebase was 50% the size, the company had some commitment to testing. Over 80% was a clear and strong commitment to testing, and over 100% meant a deeply engrained testing culture. </span></div><div style="text-align: left;"><span style="font-family: georgia;"><br />The current code base of Jacobin consists of 8,342 lines (includes: code, comments, blank lines). Of those, 4,718 lines are in tests. That is, the testing codebase is <i>130.2%</i> the size of the production code. The goal is to get that ratio even higher. Future quarterly updates will reveal our success in this effort.</span></div><p></p><h4 style="text-align: left;"><span style="font-family: georgia;">Want to help?</span></h4><div><span style="font-family: georgia;">It's always great to know a project is interesting to others. If Jacobin is interests you and you want to encourage its progress, a GitHub star is our preference. If you want to participate more directly, let me know in the comments, which are kept private. We also love code reviews, suggestions, and later on, we'll surely need folks to do testing. Whatever your interest, thanks for your time!</span></div><p><br /></p><p> </p><p><br /></p><p><br /></p><p><br /></p>Andrew Binstockhttp://www.blogger.com/profile/02636845733967051523noreply@blogger.com0tag:blogger.com,1999:blog-9620948.post-51822598396083665602021-08-05T14:50:00.001-07:002021-08-05T15:01:47.450-07:00 A Whole New Project: A JVM<p style="text-align: left;"><span style="font-family: georgia;">Ever since I started out in programming, I've wanted to undertake a programming project that was developed with the rigorous approach used in mission-critical software: write out the requirements; enforce traceability between requirements between requirements, code, and tests; and, of course, do rigorous testing. </span></p><p><span style="font-family: georgia;">The main problem has been finding the time to dedicate to such a project. There is a reason that the agile movement eschews this approach: it is the opposite of agility--it relies on an unchanging product definition, relies on extensive documentation, and does not accept the concepts of failing fast and releasing often. It's a whole different mindset to "fail never and release when ready."</span></p><p><span style="font-family: georgia;">In the light of these constraints, the ideal project is one with a well-defined set of specifications. I've decided to meet that need by writing a simplified version one of my favorite pieces of software: the Java Virtual Machine (JVM). </span></p><p><span style="font-family: georgia;">The specs for much of the JVM are published in detail and updated by the Java team at Oracle with every new release. You can find them <a href="https://docs.oracle.com/javase/specs/index.html">here</a>. On the basis of these docs alone, the JVM is the best documented virtual machine in commercial use. There are many additional resources available, such as the excellent articles by <a href="https://blogs.oracle.com/javamagazine/?search_terms=Ben%20Evans" target="_blank">Ben Evans</a> and <a href="https://shipilev.net/jvm/anatomy-quarks/" target="_blank">Aleksey Shipilev</a> (both of Red Hat) on how the innards of the JVM work. And, I should add the source code to the JVM is publicly <a href="https://code.yawk.at/java/11/java.base/jdk/internal/misc/VM.java" target="_blank">available</a>. </span></p><p><span style="font-family: georgia;">My project is entitled Jacobin and can be accessed at <a href="http://jacobin.org">jacobin.org</a>, which for the time being (and possibly permanently) points to the Jacobin project page on GitHub. There you'll find a detailed write-up of the project status.</span></p><h3 style="text-align: left;"><span style="font-family: georgia;">Choosing a Language</span></h3><p><span style="font-family: georgia;">I have spent the last eight months researching the JVM--reading the docs and articles and doing exploratory coding in various languages with which to write the Jacobin JVM. My requirements for the implementation language are simple enough: it must have decent tools and a viable ecosystem, it must compile to native code on the three major platforms (Windows, Mac, and Linux), and it must have built-in garbage collection (GC). The latter requirement is important. The JVM performs garbage collection, but I don't want to write a garbage collector. They are <i>exceedingly</i> difficult tools to write and, especially, to debug. By using a language that does its own GC, a huge amount of work has been removed from the project.</span></p><p><span style="font-family: georgia;">Three languages meet my requirements: Dart, Swift, and Go. I've written several thousand lines of code in the first two and have eliminated them from consideration. Here is why. <b>Dart</b> is a lovely language, but it's slow (even when compiled to binaries), its ecosystem is wanting, and the kind of threading it does is a poor match to the JVM. The problem with the ecosystem is exemplified by the nearly complete absence books on the language since Dart 2.0 came out a few years ago. Almost all written tutorials are way out of date. Those that are current focus, without exception, on Flutter--the UI toolkit that dominates the use cases for Dart. As a result, it's not easy to learn Dart in depth unless you want to focus primarily on Flutter. The Dart team should really address this. As to the threading model, it is based entirely on single-channel message passing: there is no shared memory. The JVM must perforce share memory between threads and so even if Dart were faster and the docs were up-to-date, it would not meet my needs.</span></p><p><span style="font-family: georgia;"><b>Swift</b> is a <i>truly </i>beautiful language. It's rich in features and has a lot of the type-checking and code safety rules of Rust, but without the endless head-banging that Rust entails. I would have loved to write the JVM in Swift, but it has several drawbacks: it doesn't run on Windows and its libraries are intimately tied to the Mac. Let me clarify. There is an official version of Swift for Windows, but it's maintained entirely by a single engineer at Google. There are effectively no docs for this version and the installation instructions don't work no matter how much tweaking and configuration I have done. The second problem is that while Swift is trying to become a language that works beyond just Apple platforms (for example, it runs fine on Linux), this worthy goal is far from especially when it comes to libraries. Consider that the equivalent of libzip (which is a core library in most languges--it is used to compress/decompress data using the zip format) is maintained by a third party on Github on a project that has at present 22 stars. The collections library has at most a handful of basic data structures, etc. Unless I want to write many of these libraries myself--which I have no desire to do--I am forced down the same road as Node developers: grabbing bits of functionality here and there from different contributors, many of which have unknown code quality. The alternative is to use Apple's Cocoa frameworks on the Mac, which would make my project Mac-only. In sum, until Swift grows its non-Mac ecosystem, it's not a viable option for this project--much to my chagrin.</span></p><p><span style="font-family: georgia;">This leaves <b>Go</b>, which is an easy-to-learn language that runs well on the major platforms and has a flourishing set of libraries, many of which are maintained by core Go developers. While it checks all the boxes, it presents its own challenges. For example, it's the only one of the languages that is not object-oriented and the transition from thinking in objects (after all, Java is my home language, so to speak) to using an imperative style of coding requires some rewiring of how I approach problems. In addition, the standard Go tools have weaknesses. For example, the testing framework is minimal--there is nothing like JUnit in terms of range of features. In the language itself, return values for errors and the lack of generics both feel a little crude, especially to someone coming from Java. Nonetheless, it looks like the best option for my project.</span></p><p><span style="font-family: georgia;">There was one other language candidate: <b>Java</b>. That is, write a JVM that runs on the JVM. I don't find this interesting at all. The code for the JVM is currently mostly written in Java and I'll be consulting it frequently--so what would I do then? Cut and paste? Rewrite the code in my preferred style? It's hard to see how that's an advantage.</span></p><h3 style="text-align: left;"><span style="font-family: georgia;">What's Next?</span></h3><p><span style="font-family: georgia;">In the next few months, I'll continue writing requirements and traceability docs and work through various Go books to transition from beginner Gopher to advanced, so that coding can proceed apace, rather than through constant searches. By that time, I should be in good position to rewrite the 2500 lines of Java-bytecode parsing routines I wrote in Swift, finish that parser, and then begin working on building the execution environment. </span></p><p><span style="font-family: georgia;">In my next blog post, I'll write about the benefits of such a project and how personal projects like this deliver unexpected rewards.</span></p><p><span style="font-family: georgia;">In the meantime, if you want to show your interest or support, follow the project on <a href="https://github.com/platypusguy/jacobin" target="_blank">GitHub</a> or give it a star, so that I know I'm not working alone in a dark alley.</span></p><p><span style="font-family: georgia;"><br /></span></p><p><br /></p>Andrew Binstockhttp://www.blogger.com/profile/02636845733967051523noreply@blogger.com0tag:blogger.com,1999:blog-9620948.post-91960236097833323462010-11-18T00:27:00.000-08:002010-11-18T00:47:30.239-08:00The Most Important Book of The Year<div><img src="http://martinfowler.com/continuousDelivery.jpg" height="216" width="163" /></div><br /><a href="http://www.amazon.com/gp/product/0321601912?ie=UTF8&tag=wwwpacificdat-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321601912">Continuous Delivery</a><div>by Jez Humble and David Farley</div><p><br />I have reviewed many books on this website and I have gone through numerous others as part of my work on the Jolt Awards, but it’s been a very long time since I’ve read a book as useful and likely game-changing as <a href="http://www.amazon.com/gp/product/0321601912?ie=UTF8&tag=wwwpacificdat-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321601912">Continuous Delivery</a>.</p> <p>The basic premise of the book is that we need to move past continuous integration into a fuller cycle of activities that go beyond build and test. Specifically, this new orientation calls for building and testing on all platforms, creating and deploying the final deliverables for all platforms—with every check-in. The benefit of this approach is that the development organization at any given moment always has: 1) immediate feedback on deployment issues, 2) a deployable binary; 3) a completely automated process to build, test, and deploy on all platforms.</p> <p>This simple concept—a kind of continuous integration on mega steroids—has profound repercussions, all of which make your process better. The first and most important is that you have to automate everything downstream from the coding. And the authors mean <i>everything</i>. The most common point where people hem and haw about automation is deployment. But Humble and Farley make it clear you have to “bring that pain forward,” and fix the process so it can be automated. (If you don’t have any idea how you might refine and automate deployment, think virtualization. Can you emulate your current systems on virtual machines and then progressively simplify deployment of the software to the point of automation? Good, you’re on your way.) </p><p>But the mechanics of deployment may be the least of your challenges (And here, the book’s name could be viewed as misleading: Deployment is only one aspect it covers.) You also have to build, run, and test the software on every platform you ship on. You’re not reasonably going to be able to do that if you have to change configurations and manually reset values for different platforms. The authors guide you to finding the one path that gets you across the river Jordan without spending 40 years in the desert of bit twiddling. The key is to use a single codebase and move the platform dependent stuff into configuration files. This is non-trivial, but the authors offer plenty of good advice.</p> <p>Testing is another topic Humble and Farley explore in great depth. Testing in the context of continuous delivery is not just running unit tests and a regression suite. No , this is running all tests—unit, integration, UAT, and so on. How to automate them effectively occupies probably the largest chunk of the book. Even if you don’t accept the continuous delivery concept, this section is worth the price of admission. It’s mind-expanding, in ways that the hundreds of articles we’ve all read about agile testing on Digg and Reddit never touch on. You see very quickly how much more automation you could do and how to get from your miserable semi-manual existence to the smooth flow of full and continuous automation.</p> <p>What impresses about the book is how the authors consistently work through hard problems. They are not daunted by them and there is no attempt to pas over them with hand waving. Hard things are examined in detail with a perspective that derives from the authors’ own extensive experience.</p> <p>I have literally never read a better book on process. I believe that going forward, this book will redefine agile process and CI; and it will have as much influence as--I have to go back to 1999, here--Fowler’s book on <a href="http://www.amazon.com/gp/product/0201485672?ie=UTF8&tag=wwwpacificdat-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0201485672">Refactoring</a> did on code.</p>Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com1tag:blogger.com,1999:blog-9620948.post-78960405699050124792010-10-25T16:39:00.000-07:002010-10-26T16:13:00.376-07:00Bluebeam's PDF Creation Tool SuiteI use a variety of PDF tools in my editorial work. I frequently create, mark up, manipulate, and combine PDFs. In addition, I contribute to the open source <a href="http://platypus.pz.org/">Platpus typesetting project</a>, whose major output format is PDFs. And the PDF plugin is my specific bailiwick. So, over the years, I've come to know a thing or two about PDFs, as well as the limitations of PDF tools.<br /><br />The standard for PDF tools has been Adobe's Acrobat suite. But this suite is expensive, somewhat quirky, and at times works poorly with other tools. Acrobat plugins to Microsoft Office and Internet Explorer are especially unreliable, and they frequently make their host programs behave erratically. I always uninstall them.<br /><br />This means I need to use other options to convert Word documents to PDF. There are several common solutions out there, none but one of them is completely satisfactory. For example, the <a href="http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&FamilyID=4d951911-3e7e-4ae6-b059-a2e79ed87041">Microsoft Office PDF plugin </a>does not embed all fonts, nor does it give you the option to do so. It does not embed the Base14 fonts.<br /><br />This is a design error (that is common). Here is its history. For many years, Adobe guaranteed that Adobe Acrobat Reader would provide 14 fonts (the so-called Base14 fonts) in all implementations. These fonts were Times Roman, Courier, and Helvetica typefaces (each in regular, bold, italic, and bold italic—so 12 fonts) plus a Symbol and a Dingbat font. The rule was you did not need to embed these fonts in PDF documents, because Acrobat Reader would supply them. This scheme never worked very well. Its first limitation was that not all Times Roman fonts looked the same, so the same document could look strikingly different on two different computers. A few years ago, Adobe quietly discontinued supporting Base14 fonts in Acrobat Reader. The result is that if you're creating a PDF for distribution, you must embed all fonts, even the old Base14 fonts, if you want it to maintain your original format and layout.<br /><br />The Microsoft Office plugin does not have this option, so as a result PDFs you generate with it are not guaranteed to look correct on other systems. And, in fact, they frequently do not.<br /><br />The PDF generator that come with Adobe Acrobat (not the Reader, but the paid tools) works better. It does offer an option to embed all fonts. However, in Word documents with many links, it fails to identify all links. And so rather than be clickable, the links show up as pure text.<br /><br />To remedy this, I tested various Word-to-PDF tools and found none that consistently met all requirements until I ran into <a href="http://www.bluebeam.com/">Bluebeam PDF Revu</a>, a tool I had not previously heard of.<br /><br />The first thing I noticed was that Bluebeam's plugins were stable and they worked correctly. The second thing I discovered was that Revu found all links in documents and by default, it embedded all fonts. So far, so good. The attention to small details in its PDFs are part of Bluebeam's DNA—it was designed as a tool for CAD users, so correctly rendering every detail of a document is a specialty.<br /><br />Like the Adobe Acrobat toolbox, Revu provides editing capabilities, with better text mark-up tools than Acrobat. It also enables you to construct your own menu of tools for faster access to frequently performed operations. Form handling, digital signatures, etc. work exactly as expected. Multi-document processing can also be automated with the product. Adobe Acrobat Pro—the comparable offering from Adobe—retails at $449 list, and $350 at <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FAdobe-22020738-Acrobat-Professional-9%2Fdp%2FB0018VF9EW%2F&tag=wwwpacificdat-20&linkCode=ur2&camp=1789&creative=9325">Amazon</a><img style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; MARGIN: 0px; BORDER-TOP: medium none; BORDER-RIGHT: medium none" border="0" alt="" src="http://www.assoc-amazon.com/e/ir?t=wwwpacificdat-20&l=ur2&o=1" width="1" height="1" />. The academic version of Acrobat can be found for the same price as the full Bluebeam Revu ($149) product. So, if you want the full range of options, better implemented than in Adobe's offering, and at a lower price, have a look at Bluebeam PDF Revu. (They offer a 30-day free trial.)Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com0tag:blogger.com,1999:blog-9620948.post-39235373883552988472010-02-04T00:52:00.001-08:002010-02-04T01:25:47.440-08:00Keeping LOC and Tests in Balance<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDb2BZVZ-N6OwcHHhQ3pZzKIVJWDguENRCKMaGylcMmqELWKs_A3hMQnEPQbWTgxQtA7lLIPQgK8tuBW8iHBM3UwdtG1Bx105gNwzHAZIFL61GUwdLhIj-EOLkBQEhNkzls-kE/s1600-h/LinesToTestsRatio.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 311px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDb2BZVZ-N6OwcHHhQ3pZzKIVJWDguENRCKMaGylcMmqELWKs_A3hMQnEPQbWTgxQtA7lLIPQgK8tuBW8iHBM3UwdtG1Bx105gNwzHAZIFL61GUwdLhIj-EOLkBQEhNkzls-kE/s400/LinesToTestsRatio.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5434312927214760274" /></a><br />The proliferation of metrics in software development threatens to take important quantitative measures and bury them beneath an avalanche of noisy numbers. Consequently, it's important to look for certain ratios and trends among the numbers to inform you whether a project is healthy. One tell-tale relation links LOCs and number of tests. These two values should grow in direct proportion to each other.<br /><br />The included diagram presents the ratio of these two values for <a href="http://platypus.pz.org">Platypus</a>, the OSS project I work on.<br /><br />As you can see, except for a few dips here and there, these numbers have stayed in lock step for the last 18 months. And, as you might expect, code coverage from these tests has similarly remained in fairly narrow range--right around 60%. <br /><br />The most typical violation of this ratio is, as you would guess, a jump in LOCs without a corresponding rise in tests. This is something managers should watch out for. With a good dashboard, they can tell early on when these trend lines diverge. This is frequently, but not always, always indicative of a problem. (For example, it could be that a lot of code without tests was imported to the project.) Whatever the cause is, managers need to find out and respond accordingly.<br /><br />(For the record, the tests counted in this diagram include unit tests and functional tests.)Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com5tag:blogger.com,1999:blog-9620948.post-5153499943771247912009-11-22T21:44:00.000-08:002009-11-22T22:10:33.259-08:00The Limitations of TDDDuring the last 12-18 months, TDD has broken into the mainstream, it seems. And now, we're starting to see some backlash, as its limitations become better understood. Here is a sample discussion from <a href="http://www.artima.com/forums/flat.jsp?forum=106&thread=272118&start=15&msRange=15">Artima.com</a>. Cédric Beust, who wrote the commentary, is not some unknown guy with a weird name. He wrote the <a href="http://testng.org/doc/index.html">TestNG</a> unit testing framework, which is second only to JUnit in popularity. He also wrote the book, <a href="http://is.gd/51w5F">Next Generation Java Testing</a>, which is probably the best book on pragmatic software testing that I've read in a long time. Here goes...<br /><br /><blockquote><i>> That's an interesting point. Are you, in effect, saying<br />> that unit testing is overly emphasized, and at the expense<br />> of other forms of testing?</i><br /><br />This has also been my experience, although to be honest, I see this problem more in agile/XP literature than in the real world.<br /><br />This is the reason why I claim that:<br /><br />- TDD encourages micro-design over macro-design<br />- TDD generates code churn<br /><br />If you obsessively do TDD, you write tests for code that you are pretty much guaranteed to throw away. And when you do that, you will have to refactor your tests or rewrite them completely. Whether this refactoring can be done automatically or not is beside the point: you are in effect creating more work for yourself.<br /><br />When I start solving a problem, I like to iterate two or three times on my code before I'm comfortable enough to write a test.<br /><br />Another important point is that unit tests are a convenience for *you*, the developer, while functional tests are important for your *users*. When I have limited time, I always give priority to writing functional tests. Your duty is to your users, not to your test coverage tools.<br /><br />You also bring up another interesting point: overtesting can lead to paralysis. I can imagine reaching a point where you don't want to modify your code because you will have too many tests to update (especially in dynamically typed languages, where you can't use tools that will automate this refactoring for you). The lesson here is to do your best so that your tests don't overlap.<br /><br />--Cedric Beust </blockquote>Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com11tag:blogger.com,1999:blog-9620948.post-17949653428629830772009-08-04T14:02:00.000-07:002009-08-04T14:16:27.059-07:00My Interview with Alexander Stepanov and Paul McJonesInformIT.com has posted my <a href="http://www.informit.com/articles/article.aspx?p=1383185">interview</a> with <a href="http://en.wikipedia.org/wiki/Alexander_Stepanov">Alexander Stepanov</a> (of <a href="http://en.wikipedia.org/wiki/Standard_Template_Library">STL</a> fame) and his co-author <a href="http://www.mcjones.org/paul/">Paul McJones</a>. Their just-released book, <a href="http://is.gd/22DvU">Elements of Programming</a>, tries to map algorithm implementations back to symbolic logic and algebraic theorems, thereby--in theory--improving their design and correctness.<br /><br />In the discussion, we broach many topics that derive from this approach to programming.Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com0tag:blogger.com,1999:blog-9620948.post-85899400837962571092009-07-25T15:40:00.001-07:002009-07-25T17:12:00.304-07:00Groovy BooksI have been using Groovy to write functional tests for <a href="http://platypus.pz.org/">Platypus</a>, the open-source typesetting project I work on. I am likely to make Groovy the default scripting language for Platypus in the next milestone. In the process, I've had to come up to speed on Groovy and I've been reading through and looking over the various Groovy titles on the market. Here's my take.<div><br /></div><div>The Groovy bible today, without the slightest doubt, is <a href="http://www.amazon.com/gp/product/1932394842?ie=UTF8&tag=wwwpacificdat-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=1932394842">Groovy in Action</a><img src="http://www.assoc-amazon.com/e/ir?t=wwwpacificdat-20&l=as2&o=1&a=1932394842" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;"/> which at 650+ pages is also the most detailed book. Its principal limitation is that Groovy has undergone several revisions since it came out. Because of this, a second edition is being written. Early access to e-drafts of that edition are available <a href="http://manning.com/koenig2/">here</a>, although little as yet has been published.</div><div><br /></div><div>If you'd like a shorter and more up-to-date introduction to Groovy, I recommend <a href="http://www.amazon.com/gp/product/1934356093?ie=UTF8&tag=wwwpacificdat-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=1934356093">Programming Groovy</a><img src="http://www.assoc-amazon.com/e/ir?t=wwwpacificdat-20&l=as2&o=1&a=1934356093" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />by Venkat Subramaniam. At less than 300 pages, it's a quick read, provides all the needed info quickly, and covers all the highlights, with a good balance of detail.<br /></div><div><br /></div><div>Many people consider <a href="http://grails.org/">Grails</a> to be the killer app for Groovy. It's a web framework that rides above Spring and Hibernate and removes much of the complexity of using those components. If you are learning Groovy to use Grails, then <a href="http://www.amazon.com/gp/product/B001U0OFA0?ie=UTF8&tag=wwwpacificdat-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=B001U0OFA0">Beginning Groovy and Grails</a><img src="http://www.assoc-amazon.com/e/ir?t=wwwpacificdat-20&l=as2&o=1&a=B001U0OFA0" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />is an excellent choice. It's clear, approachable, and teaches you enough Groovy to be able to follow the tutorial on Grails.<br /></div><div><br /></div><div>Once you get comfortable with basic Groovy, you'll quickly find yourself pining for a book of recipes that shows you how to quickly get basic tasks done using Groovy metaphors. There are two somewhat flawed recipe books on the market. The first is <a href="http://www.amazon.com/gp/product/0978739299?ie=UTF8&tag=wwwpacificdat-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0978739299">Groovy Recipes</a><img src="http://www.assoc-amazon.com/e/ir?t=wwwpacificdat-20&l=as2&o=1&a=0978739299" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />from Scott Davis, a well-regarded lecturer in the Groovy area. While calling itself a recipe book, it frequently diverges into tutorials and odd humor--both of which are obstacles when trying to find information. Some important topics are not covered at all, such as testing--which is one of the major areas where Groovy benefits Java. Database access is also not covered. In other areas, Davis' explanations seem to lack an understanding of what the user would be looking for. Nonetheless, I have successfully used some of Davis' recipes in my work. A good alternative is <a href="http://www.amazon.com/gp/product/B001W0Z8QS?ie=UTF8&tag=wwwpacificdat-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=B001W0Z8QS">Groovy and Grails Recipes</a><img src="http://www.assoc-amazon.com/e/ir?t=wwwpacificdat-20&l=as2&o=1&a=B001W0Z8QS" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />from Bashar Abdul-Jawad. This title is a true recipe book and very readable. The Groovy portion is too short, however, and an important section on file recipes (which <i>does</i> appear in the Davis book) is omitted. However, if you're learning Groovy to get to Grails, this is the best choice. And Abdul-Jawad does a good job understanding what readers are looking for.</div><br /><div>Ideally, O'Reilly would publish one of its trademark comprehensive recipes book and we could all settle on that. However, when I contacted O'Reilly about upcoming Groovy titles, the company indicated it had none in the immediate pipeline. </div><div><br /></div><div>That's pretty much it for Groovy books; although there are several others that focus exclusively on Grails. One publisher, Apress, seems to dominate that Grails market. The two titles above that cover Grails are from Apress as is the <a href="http://www.amazon.com/gp/product/B001WAK7P0?ie=UTF8&tag=wwwpacificdat-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=B001WAK7P0">Definitive Guide to Grails</a><img src="http://www.assoc-amazon.com/e/ir?t=wwwpacificdat-20&l=as2&o=1&a=B001WAK7P0" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />, written by Graeme Rocher, who designed Grails. In the past I've been skeptical of Apress books due to wide variations in their quality, but the Groovy/Grails titles I've examined have been consistently of high quality.</div><div><br /></div><div>As Groovy gains a wider audience, I expect more titles to emerge from all the technical book publishers.<br /><br /><br /><br /><br /></div>Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com4tag:blogger.com,1999:blog-9620948.post-60063728254643154352009-05-20T14:44:00.000-07:002009-05-20T15:19:20.621-07:00The Fan programming language: compile to Java and .NETI have recently been playing with <a href="http://www.fandev.org">Fan</a>, a programming language that reminds me a lot of Groovy, but has additional capabilities, such as actors. Its binaries run either on the JVM or .NET. Below is my recent column in <a href="http://www.sdtimes.com">SDTimes</a> about the language. <div><p class="MsoNormal"></p><blockquote><p class="MsoNormal">In recent times, we are seeing an extraordinary proliferation of new languages. On one hand, thousands of domain-specific languages (DSLs) have been spawned by the advent of tools that facilitate their creation. On the other hand, we find an equal surge in full-scale, general-purpose programming languages.</p> <p class="MsoNormal"><o:p> The renaissance of these larger programming languages derives from several advances: 1) a renewed interest in dynamic languages and their benefits; 2) hardware that’s fast enough to run dynamic languages rapidly; and 3) the existence of two run-time environments—the JVM and the .NET CLR—that are widely used, well understood, and fast. As a result, we have an embarrassment of language choices that was inconceivable a decade ago.</o:p></p> <p class="MsoNormal">In this column, I have previously highlight various interesting options among these languages: Ruby, Groovy, D, NetRexx, and a few others that elegantly address specific problems. Recently, I have been spending time with the Fan programming language, which while still early in its development cycle, is more finished and mature than most new languages at this point in their development.</p> <p class="MsoNormal"><a href="http://www.fandev.org">Fan </a>is a dynamic, OO language that runs on the JVM <i style="mso-bidi-font-style:normal">and</i> the .NET CLR. It does this by generating intermediate code (called fcode) that is dynamically translated into Java bytecodes or a .NET DLL at startup. This step introduces a slight pause, after which programs run at full “native” speed for the given environment.</p> <p class="MsoNormal">New languages arise because a developer needed to solve a problem that was not addressed well by common alternatives. The developers of Fan, a pair of brothers—Brian and Andy Frank—worked on embedded Java applications and found it difficult to sell the accompanying software to customers who were committed to Windows Mobile and .NET. So, they decided to write Fan to solve the problem and to keep it small enough that it could fit easily in a mobile device. </p> <p class="MsoNormal">In the process, they removed language verbosity and added features they wanted. Their vision is remarkably balanced and complete. The language, on the verge of a freezing its 1.0 features, offers: dynamic typing and/or strong typing (<i style="mso-bidi-font-style:normal">à la</i> Groovy), closures and first-class functions, extensive concurrency support (thread-safe classes with immutability specified, threads with built-in message passing, and actors), and elegant handling of various namespace issues. Low-level features include default method parameters, nullable data types, built-in field accessors, unchecked-only exceptions, and simplified numerics. The numerics handle the overflow problem that is the favorite of language puzzle writers: all integers are longs and all floats are doubles. So either type uses 64-bits and effectively does not overflow. Chars are 16-bit UTF entities.</p> <p class="MsoNormal">A particularly interesting aspect of Fan is the libraries. As Brian Frank told me, “Solving the JVM/CLR portability was the easy part. The hard part was what to do with the libraries and APIs.” What the brothers did was to rethink the API sets, eliminate cruft, and use a different concept of grouping. Whereas .NET and Java both use a large number of packages that include moderate numbers of classes, Fan uses few packages that contains large numbers of classes. The result is that a developer can almost always can guess correctly which package to link to for a specific need. In addition, Fan has sensible, built-in library defaults. For example, all files I/O defaults to buffered.</p> <p class="MsoNormal">The good design of a language can take it only so far. To succeed, it needs good tools, good docs, and an active community. The language tools (compiler, etc.) are all open source and written in Fan. The code is clean and surprisingly readable. As to IDE support, there is currently a plugin for JetBrains IDEA and one in the very early stages for Eclipse . The Frank brothers do all their coding in regular text editors.</p> <p class="MsoNormal">The documents are very good. Probably, the best I’ve seen for any new language at this point and far better than much older “new” languages, such as D. The website is well organized and elegant; and the tutorials and “cookbook” entries clean and plentiful. It’s difficult to assess language community size in general, but more so with Fan because it does not figure on Tiobe, due I suspect to the difficulty of teasing out data for a language named Fan. For this reason and for richer Google search results, there is a move afoot to change the name of the language. Nonetheless, the community is definitely small and active. The latter aspect due to the responsiveness of the Frank brothers to users’ questions, requests, and defect reports. </p> <p class="MsoNormal">Fan solves a lot of problems elegantly. If it continues growing as it has during the past year, I anticipate it will evolve into an attractive solution for some development organizations.</p></blockquote><p class="MsoNormal"></p></div><div><blockquote></blockquote>The biggest challenge right now is the early stage in which most IDE plugins are currently found. A second limitation, which is about to be fixed in the upcoming point release, is that libraries and binary modules are all placed by default in the same directory. The discussion on this point, found on the language's discussion boards, shows the attentive regard of the Frank brothers for their users as they kicked around various schemes, elicited comments, and posted thoughtful replies. It's one of the most spam-free, low-noise discussion groups I've been a part of in a long while. I expect good things from this language.</div>Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com6tag:blogger.com,1999:blog-9620948.post-15937181006847245562009-01-05T01:01:00.000-08:002009-01-05T13:11:16.662-08:00The Agile Rules in HP's Original GarageAccording to a recent HP poster, these were the rules in Bill Hewlett and Dave Packard's famous garage:<div><br /></div><div><span class="Apple-style-span" style=";font-family:georgia;font-size:14;" ><li style="margin: 0px; padding: 0px;">Believe you can change the world.</li><li style="margin: 0px; padding: 0px;">Work quickly, keep the tools unlocked, work whenever.</li><li style="margin: 0px; padding: 0px;">Know when to work alone and when to work together.</li><li style="margin: 0px; padding: 0px;">Share tools, ideas. Trust your colleagues.</li><li style="margin: 0px; padding: 0px;">No Politics. No bureaucracy. (These are ridiculous in a garage).</li><li style="margin: 0px; padding: 0px;">The customer defines a job well done.</li><li style="margin: 0px; padding: 0px;">Radical ideas are not bad ideas.</li><li style="margin: 0px; padding: 0px;">Invent different ways of working.</li><li style="margin: 0px; padding: 0px;">Make a contribution every day. If it doesn’t contribute, it doesn’t leave the garage.</li><li style="margin: 0px; padding: 0px;">Believe that together we can do anything.</li><li style="margin: 0px; padding: 0px;">Invent.</li></span></div><div><br /></div><div>Curiously, it sounds like something the agile guys might have written (had they not written the manifesto). I prefer this wording because of its greater applicability and more dynamic presentation.<br /><div><br /></div></div>Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com5tag:blogger.com,1999:blog-9620948.post-90475024772654443242008-11-13T19:23:00.000-08:002008-11-14T11:57:27.038-08:00Bob Martin's "Clean Code" ReviewedI have gone through "Uncle Bob" Martin's new book, <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FClean-Code-Handbook-Software-Craftsmanship%2Fdp%2F0132350882%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1226633218%26sr%3D8-1&tag=wwwpacificdat-20&linkCode=ur2&camp=1789&creative=9325">Clean Code,</a><img src="http://www.assoc-amazon.com/e/ir?t=wwwpacificdat-20&l=ur2&o=1" alt="" style="border: medium none ! important; margin: 0px ! important;" border="0" width="1" height="1" />which is a lenthy presentation of rules that will help Java developers write better code. It's similar to Kent Beck's <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FImplementation-Patterns-Addison-Wesley-Signature-Kent%2Fdp%2F0321413091%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1226640039%26sr%3D8-1&tag=wwwpacificdat-20&linkCode=ur2&camp=1789&creative=9325">Implementation Patterns,</a><img src="http://www.assoc-amazon.com/e/ir?t=wwwpacificdat-20&l=ur2&o=1" alt="" style="border: medium none ! important; margin: 0px ! important;" border="0" width="1" height="1" />except more code-fixated. Clean Code has some good points, but it contains several weaknesses that seem to have gone entirely by the reviewers on Amazon. So, here's the scoop.<br /><br />First of all, it's well hidden, but the book is only partially written by Bob Martin. Many chapters are written by other consultants who work at Martin's company--many of whom I've never heard of. The one stand-out exception is Michael Feathers, whose chapter on error handling is one of the clearest in the book. I wish he had written more.<br /><br />The main body consists primarily of explaining various coding rules that Martin calls heuristics and to which he assigns coded abbreviations for later reference. Alas, unlike patterns that have meaningful names as shortcuts, Martin chooses meaningless notations such as C2 and G26. So, "the function should do nothing but compacting[G30]" is a shortcut for the author, but a pain for the reader who has to cross-reference these references repeatedly to know what Martin is talking about.<br /><br />Unlike Beck's book, there is no theoretical framework to Martin's prescriptions. The book is a series of examples from which he teases this rule and that. Because of this lack of framework there is a certain desultory aspect--the rules come in seemingly random order.<br /><br />Some of them make you want to leap up and clap. For example, his rule that Javadoc should not contain HTML. How many times I've come to the same conclusion! I want to read comments in code easily. The small lift that HTML brings to Javadoc pages is not in anyway worth the difficulty it adds to the reading of comments in code. Bob Martin's one of the first persons I've encountered to say so unequivocally.<br /><br />Other rules are good, but later contradicted. For example, Martin states that you should never leave commented-out code in place. [C5] As he points out, no one knows why it's commented out and so it remains in place forever. However, later on in an example of refactoring code per his own rules, Martin comments out large blocks of code without an explanation of how that squares with his earlier advice. (p.374)<br /><br />Martin also uses questionable coding preferences. For example, all of his code uses indents of 2 columns. 2 columns? It makes every routine look like a solid chunk of code. It's clearly not a practice to be recommended.<br /><br />A large portion of the book is an example of Martin refactoring someone else's code. He takes a long piece from an OSS project and proceeds to "improve" it. I found this section uncompelling. Perhaps because in Fowler's masterpiece <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FRefactoring-Improving-Existing-Addison-Wesley-Technology%2Fdp%2F0201485672%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1226640224%26sr%3D1-1&tag=wwwpacificdat-20&linkCode=ur2&camp=1789&creative=9325">Refactoring,</a><img src="http://www.assoc-amazon.com/e/ir?t=wwwpacificdat-20&l=ur2&o=1" alt="" style="border: medium none ! important; margin: 0px ! important;" border="0" width="1" height="1" />each refactoring magically transforms the code. By comparison, Bob Martin's work seems journeyman-like. I didn't find the initial code interesting nor did I find Martin's cleaned-up version luminous. I was expecting a before-and-after scenario that would make me sit up and take notice. Instead, the exercise felt preachy, condescending at times, and ultimately not terribly convincing.<br /><br />My last gripe addresses an inexcusable error: typos. There aren't many but they are frequent enough to be distracting. For example, Martin seemingly does not understand the difference between <span style="font-style: italic;">it's</span> and <span style="font-style: italic;">its</span>. (p. 272, p. 296<span style="font-style: italic;">,</span> among others) And his code contains typos too. (p. 309). This carelessness erodes credibility. Books that preach quality should be flawless at the level of spelling and grammar.<br /><br />Overall, I think some organizations can use several of Martin's heuristics as a means of boosting their in-house coding standards. But I doubt that careful coders will find much of value. Those developers will be better served by Beck's <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FImplementation-Patterns-Addison-Wesley-Signature-Kent%2Fdp%2F0321413091%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1226640039%26sr%3D8-1&tag=wwwpacificdat-20&linkCode=ur2&camp=1789&creative=9325">Implementation Patterns,</a><img src="http://www.assoc-amazon.com/e/ir?t=wwwpacificdat-20&l=ur2&o=1" alt="" style="border: medium none ! important; margin: 0px ! important;" border="0" width="1" height="1" />which is based on principles and so communicates much more information in fewer words. Since my review of Beck's book, I must confess my admiration for it has deepened, and it's the volume I would recommend if you're looking to write cleaner code.Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com8tag:blogger.com,1999:blog-9620948.post-89079292286157250672008-09-28T18:07:00.001-07:002008-09-28T18:34:51.668-07:00Banishing Return Status CodesThe most enduringly popular post on this blog is <a href="http://binstock.blogspot.com/2008/04/perfecting-oos-small-classes-and-short.html">Perfecting OO's Small Classes and Short Methods</a>, which presents a short series of stringent guidelines to help an imperative-trained developer master OO. <br /><br />If I were to add one item to the list, it would be: Don't use return codes to indicate the status of an action. Developers trained in languages such as C have the habit of using return codes to indicate the success or the nature of failure of the work done by a function. This approach is used because of the lack of a structured exception mechanism. But when exceptions are part of the language, the use of status codes isa poor choice. Among the key reasons are: many status codes are easily ignored; developers will expect problems to be reported via the exception mechanism; exceptions are much more descriptive. And finally, exceptions enable return codes to be used for something useful--namely returning a data item.<br /><br />Astute readers will note that in Java, null is frequently used as a return value to indicate a problem (as in Collections). This practice subverts the previous points, and it too should be avoided. Returning a null presents code with many problems it should not have to face. The first is the risk of a null-pointer blow-up because the return value was accessed without being checked. This leads to the code bloat of endless null value checks. A much better solution, which avoids this problem, is to return an empty item (empty string, empty collection, etc.). This too communicates that no data item fulfilled the function's mandate, but it does not risk the null-pointer problem, and it frequently requires no special code to handle the error condition.<br /><br />Hence, if your OO code is characterized by heavy reliance on return codes (many of which I am certain are not checked), consider rewriting it in favor of exceptions and use return statements solely for returning non-null data items.Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com16tag:blogger.com,1999:blog-9620948.post-53822908865281276102008-09-01T17:36:00.000-07:002008-09-01T18:14:25.141-07:00A Parameter-Validation Smell and a SolutionLast week, <a href="http://blog.jeffreyfredrick.com/">Jeff Fredrick</a> and I did a day-long code review of <a href="http://platypus.pz.org">Platypus</a>. We used a pair-programming approach, with Jeff driving and I helping with the navigation. Eventually, we got into the input parser, which parses input lines into a series of tokens: text, commmands, macros, and comments. Macros can require a second parsing pass, and commands often require additional parsing of parameters. <br /><br />Once you get a parser working well (that is, it passes unit and functional tests, and it handles errors robustly), you generally don't want to mess with refactoring it. Experience tells you that parsers have hideous code in them and wisdom tells you to leave it alone. However, we launched in. <br /><br />A frequent cause of <a href="http://dictionary.reference.com/browse/otiose">otiose</a> code was my extensive parameter checking. Parameters were validated at every step as tokens passed through multiple levels of parsing logic. Likewise, the movement of the parse point was updated multiple tiems as the logic resolved itself back up the processing stack. This too had to be validated repeatedly.<br /><br />Jeff came up with an elegant refactoring that I could not find in the usual sources. He created an inner class consisting of the passed variables, a few methods for validating them, and a few more methods for manipulating them. <br /><br />This class was then passed to the methods in lieu of the individual parameters--thereby reducing the number of parameters to one or two. And because the class constructor verified the initialization of the fields, I need only to check whether the passed class was null, rather than validate each of the internal fields. <br /><br />The effect was to reduce complexity of already complex code, enforce DRY, and place the validation of the variables inside a class that contained them--a set of small, but important improvements. And like many of the best refactorings, it seems obvious in retrospect.<br /><br />So, if you find your class's methods are repeatedly validating the same parameters, try bundling them in an inner class along with their validation logic. You'll like the results.Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com5tag:blogger.com,1999:blog-9620948.post-58484484965117843422008-06-03T16:28:00.000-07:002008-06-03T17:25:39.083-07:00The Handiest Java Book in Years.<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnnH1Hcp1iZ6mgK-MJC6NkrsPSczE_-xZyatvHu5Lta5qa9tz4rljFKsar-VngzK2eKCFmmQF9mXEwQyeHU2-RH8J0nBOt7gQmyNm2je6ncUNA83H-YfzS3aroWctNNM9lb-65/s1600-h/CoverJavaPowerTools.jpg"><img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnnH1Hcp1iZ6mgK-MJC6NkrsPSczE_-xZyatvHu5Lta5qa9tz4rljFKsar-VngzK2eKCFmmQF9mXEwQyeHU2-RH8J0nBOt7gQmyNm2je6ncUNA83H-YfzS3aroWctNNM9lb-65/s320/CoverJavaPowerTools.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5207815633202370834" /></a><br />One of the constant challenges I have as a Java developer is keeping up with the numerous good FOSS dev tools. I no sooner start testing one tool and adapting my project to it, when a new one comes along. Being an analyst and naturally curious, this new product (or new release) represents a constant temptation. Is it better than what I am using? How much effort is required to try it out? What does it do better? On and on. <br /><br />I can put a lot of those concerns to rest now. I just received a copy of <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FJava-Power-Tools-Ferguson-Smart%2Fdp%2F0596527934%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1212538356%26sr%3D8-1&tag=wwwpacificdat-20&linkCode=ur2&camp=1789&creative=9325">Java Power Tools</a><img src="http://www.assoc-amazon.com/e/ir?t=wwwpacificdat-20&l=ur2&o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> from O'Reilly and it's exactly what I've been looking for. It contains deep explanations of the principal FOSS dev tools in 10 major categories. These explanations are not two- or four-page summaries, but in-depth expositions that provide crucial info on the strengths and weaknesses of the product. The author, John Smart, then provides detailed tutorial on using the product. It's clear he's spent lots of time exploring the dark corners of each tool. And he makes good use of that knowledge in his comparisons and comments on the products.<br /><br />If you want to spend an hour or so coming up to speed on what a product is about before installing it (and without having to work through the usually limited docs), this book will get you there faster and enable you get an overview of a whole lot of tools quickly and with the assurance you have a clear understanding. Here are the tools that are covered, followed by the number of pages for each one in parentheses:<br /><br />BUILD TOOLS: Ant (55), Maven (60)<br />SCM: CVS (20), Subversion (78)<br />CI: Continuum (24p) Cruise Control (19) LuntBuild (32) Hudson (19)<br />IM: Openfire (12)<br />UNIT TESTING: JUnit (20) TestNG (25) Cobertura (17)<br />OTHER TESTING: StrutsTestCase (10) DbUnit (44p) JUnitPerf (10) JMeter (20) SoapUI (22) Selenium (30( Fest (9)<br />PROFILING: with Sun tools (16) with Eclipse (15)<br />DEFECT MANAGEMENT: Bugzilla (20) Trac (35)<br />QUALITY: Checkstyle (20) PMD (18p) FindBugs (12) Jupiter (18) Mylyn (14p)<br /><br />All told, 856 pages of crisp, well-written explanations. A must-have reference for the bookshelf.Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com3tag:blogger.com,1999:blog-9620948.post-76427374378965909402008-05-22T23:15:00.000-07:002008-05-23T00:20:19.073-07:00Is the popularity of unit tests waning?Before getting into my concerns about whether unit testing's popularity has peaked, let me state that I think unit testing is <span style="font-style:italic;">the</span> most important benefit wrought by the agile revolution. I agree that you can write perfectly good programs without unit tests (we did put man on the moon in 1969, after all), but for most programs of any size, you're likely to be <span style="font-style:italic;">far</span> better off using unit tests than not.<br /><br />The problem is that only a small subset of developers understand that. And recent data points suggests that the number of programmers who use unit tests is not exactly growing quickly. I'll list some of the data points below that I've been developing for my column in <span style="font-style:italic;">SD Times</span>.<br /><br />1) Commercial products on the wane. Agitar was a company whose entire fate was tied to the popularity of unit testing. Despite very good products, a free service to auto-generate unit tests for your code, and some terrific exponents (especially Alberto Savoia and Jeff Frederick) to tell their story, the company closed a down a few weeks ago, essentially having come to the conclusion that it could never be sold at a price that could repay investors. So rather than ask for more funding, it closed down. If unit testing were gaining popularity robustly, Agitar surely would have come to a different conclusion.<br /><br />2) Few OSS products. Except for the xUnit frameworks themselves, few FOSS tools for unit testing have been adopted. The innovative <a href="http://jester.sourceforge.net/">Jester project</a>, which built a tool that looked for untested or poorly tested logic, essentially stopped development a long time ago because to quote the founder, Ivan Moore, in a comment to me "so few sites are into unit testing enough to care about perfecting their tests." <br /><br />3) Major Java instructors aren't teaching it. Consider <a href="http://java.sun.com/developer/technicalArticles/Interviews/community/horstmann_qa.html">this interview</a> with Cay Horstmann, co-author of the excellent <a href="http://is.gd/kFU">Core Java</a> books. (He asks, "If so many experienced developers don't write unit tests, what does that say?" In speculating on an answer, he implies that good developers don't need unit tests. Ugh!) <br /><br />4) Unit testing books are few and far between. I am seeing about one new one a year. And as yet, not a single book on JUnit 4, which has been out for nearly three years(!).<br /><br />5) Alternative unit-testing frameworks, such as the excellent <a href="http://testng.org/doc/">TestNG</a>, are essentially completely invisible. I was at a session on scripting this spring at <a href="http://www.sdexpo.com/">SD West</a> and in a class of 30 or so, two people had heard of TestNG (the teacher and I).<br /><br />I could speculate on causes, but I have no clear culprit to point to. Certainly, unit testing needs to be evangelized more. And evangelized correctly. The folks who insist on 100% code coverage are making a useful tool unpalatable to serious programmers (as discussed <a href="http://tapestryjava.blogspot.com/2008/02/unit-testing-crisis-of-faith.html">here</a> by Howard Lewis Ship, the inventor of <a href="http://tapestry.apache.org/">Tapestry</a>). But, I think the cause has to be something deeper than this. I would love to hear thoughts from readers in real-world situations where unit testing has been abandoned, cut back, or simply rejected--and why.<br /><br />It would be a shame to have unit testing disappear and its current users viewed as aging, pining developers hankering for a technology the world has largely passed by. That would return programmers to the tried-and-true practice of glassy-eyed staring at a debugger for hours--something I have not missed at all.Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com45tag:blogger.com,1999:blog-9620948.post-75998279858862782892008-04-25T15:01:00.000-07:002008-04-25T15:08:17.383-07:00Knuth Interview PostedMy interview with Donald Knuth is now <a href="http://www.informit.com/articles/article.aspx?p=1193856">posted</a>. It's a long piece, that has some unusually interesting points, including:<br /><br />- why Knuth doesn't believe in designing code for reuse<br />- he's most unconvinced of multithreading and multicore on the desktop<br />- discussion of the tools he uses to program and write (including Ubuntu)<br />- etc.<br /><br />A very fun read (and a fun interview to do).Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com7tag:blogger.com,1999:blog-9620948.post-19633986217675024102008-04-23T22:57:00.000-07:002008-04-23T23:12:25.271-07:00Perfecting OO's Small Classes and Short MethodsIn <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FThoughtWorks-Anthology-Technology-Innovation-Programmers%2Fdp%2F193435614X%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1209017123%26sr%3D8-1&tag=wwwpacificdat-20&linkCode=ur2&camp=1789&creative=9325">The ThoughtWorks Anthology</a><img src="http://www.assoc-amazon.com/e/ir?t=wwwpacificdat-20&l=ur2&o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> a new book from the Pragmatic Programmers, there is a fascinating essay called “Object Calisthenics” by Jeff Bay. It’s a detailed exercise for perfecting the writing of the small routines that demonstrate characterize good OO implementations. If you have developers who need to improve their ability to write OO routines, I suggest you have a look-see at this essay. I will try to summarize Bay’s approach here. <br /><br />He suggests writing a 1000-line program with the constraints listed below. These constraints are intended to be excessively restrictive, so as to force developers out of the procedural groove. I guarantee if you apply this technique, their code will move markedly towards object orientation. The restrictions (which should be mercilessly enforced in this exercise) are:<br /><br />1. Use only one level of indentation per method. If you need more than one level, you need to create a second method and call it from the first. This is one of the most important constraints in the exercise. <br /><br />2. Don’t use the ‘else’ keyword. Test for a condition with an if-statement and exit the routine if it’s not met. This prevents if-else chaining; and every routine does just one thing. You’re getting the idea.<br /><br />3. Wrap all primitives and strings. This directly addresses “primitive obsession.” If you want to use an integer, you first have to create a class (even an inner class) to identify it’s true role. So zip codes are an object not an integer, for example. This makes for far clearer and more testable code.<br /><br />4. Use only one dot per line. This step prevents you from reaching deeply into other objects to get at fields or methods, and thereby conceptually breaking encapsulation.<br /><br />5. Don’t abbreviate names. This constraint avoids the procedural verbosity that is created by certain forms of redundancy—if you have to type the full name of a method or variable, you’re likely to spend more time thinking about its name. And you’ll avoid having objects called Order with methods entitled shipOrder(). Instead, your code will have more calls such as Order.ship().<br /><br />6. Keep entities small. This means no more than 50 lines per class and no more than 10 classes per package. The 50 lines per class constraint is crucial. Not only does it force concision and keep classes focused, but it means most classes can fit on a single screen in any editor/IDE.<br /><br />7. Don’t use any classes with more than two instance variables. This is perhaps the hardest constraint. Bay’s point is that with more than two instance variables, there is almost certainly a reason to subgroup some variables into a separate class. <br /> <br />8. Use first-class collections. In other words, any class that contains a collection should contain no other member variables. The idea is an extension of primitive obsession. If you need a class that’s a subsumes the collection, then write it that way. <br /><br />9. Don’t use setters, getters, or properties. This is a radical approach to enforcing encapsulation. It also requires implementation of dependency injection approaches and adherence to the maxim “tell, don’t ask.” <br /><br />Taken together, these rules impose a restrictive encapsulation on developers and force thinking along OO lines. I assert than anyone writing a 1000-line project without violating these rules will rapidly become much better at OO. They can then, if they want, relax the restrictions somewhat. But as Bay points out, there’s no reason to do so. His team has just finished a 100,000-line project within these strictures.Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com38tag:blogger.com,1999:blog-9620948.post-31883449638146864572008-04-07T22:20:00.000-07:002008-04-07T22:49:31.735-07:00Easy Does It With easybI just got back from the <a href="http://www.citconf.com/">CITcon conference</a>, which is the thrice-yearly confab of agile developers who use continuous integration (the "CIT" in the conference name). This was my second time at CITcon. It's an open-space conference that is--surprise!--free, and chock-a-block full of good information. The principal reason it's so informative is that anyone committed enough to CI to go to a conference has probably spent a lot of time thinking about how to solve problems of build and test at his/her site. And this concern and reflection on these issues is amply evident in the discussions in the hallways and the informal presentations.<br /><br />All the sessions I attended were thought-provoking. But probably the most interesting was a presentation by <a href="http://www.nofluffjuststuff.com/speaker_view.jsp?speakerId=32">Andy Glover</a>, the president of <a href="http://www.stelligent.com">Stelligent</a>, an agile consultancy. He runs a <a href="http://thediscoblog.com/">great blog</a> in which has been touting a tool called <a href="http://easyb.org/">easyb</a>, which enables you to script unit tests so that they describe a scenario (rather than a code feature) and then test for the expected result. I've read Andy's enthusiasm for easyb, but it wasn't until I saw him demo it that I understood what the excitement was about. <br /><br />The key benefits are 1) you can show a non-programmer (like the manager who is expecting the software any day now) that you have written tests that match every one of his requirements--easyb enables you to do this by writing the test in near English language; 2) you can test at a slightly higher level than the unit test: rather than test tiny features individually, you can quite easily test a succession of conditions that are chained together. <br /><br />This approach is called--a little misleadingly,--<a href="http://en.wikipedia.org/wiki/Behavior_driven_development">behavior-driven development</a>; which was an immediate turn off for me. I really don't want to learn another x-driven development. I just want to do what I do better. And I think easyb might just be such a tool. So, don't worry about the name, and hop over to the easyb <a href="http://www.easyb.org/">website</a> for a quick look-see. You'll like what you find.Andrew Binstockhttp://www.blogger.com/profile/16321156191558412680noreply@blogger.com0