Bob Balaban's Blog

     
    alt

    Bob Balaban

     

    Some Interesting Tech I’ve Been Involved With Lately

    Bob Balaban  April 20 2013 04:58:50 PM
    Greetings, geeks!

    Some of you have been wondering what I've been up to lately. No, not a stealth-mode startup, not a new API for Notes/Domino, nothing like that.
    In fact, I'm at about the 6-month mark in a whole new (to me) tech area: storage and storage management. It's one of those things that's a whole lot more complicated than you'd ever think, until you start to dig into it. Me, I thought a "disk" started and ended with that box on the end of a USB cable that you plug into a laptop. No. That's just the simplest kind of disk.

    Anyway, I now work at a company called NetApp, that makes the most advanced storage systems (and no, a "storage system" is not a closet-organizer!) on the market. I tried (as always) to explain to my mom and dad what I do all day, and it was hard, they're not "computer people". But I found some awesomely cool writeups that at least start to illustrate what goes on in the world of storage, and I thought I'd share.

    First, CERN. We all know that anything having to do with CERN is automatically very cool. Here's some stuff on what NetApp does for CERN:
    http://www.netapp.com/us/media/ds-3365-0812.pdf

    High-energy proton collision experiments generate a LOT of data, very quickly (I heard it can be at rates around 6 gigabytes per second), and you have to have "storage" that can accommodate it.

    So that's how my company mainly makes money, "storage systems". But that's not the area I work in myself. I'm working on a product called "OnCommand/Insight" (OCI), which is more on the data center management side of things. It inventories all of the important devices in your data center (storage, of course, but also switches, "hosts" (VMs and so on) etc.), and reports not only on the inventory (what devices you have, what's connected to what, like that), but on the performance and utilization of those devices: do you have storage that isn't being used by anyone? Do you have redundant connectivity from hosts to disks? Do you have RAID arrays that need servicing? And so forth.

    Here's a page that describes more comprehensively than I can here what it's all about:
    http://www.netapp.com/us/products/management-software/oncommand-insight/insight-library.aspx

    So, it's great fun. NetApp is a good company to work for, the technology is interesting and pretty deep, and it really makes a big difference to a lot of people, even if it's mostly "back-room". When you hear about "big data", or "analytics" or "cloud", start thinking NetApp!

    Geek ya later!

    Follow me on Twitter @LooseleafLLC
    This article ©Copyright 2013 by Looseleaf Software LLC, all rights reserved. You may link to this page, but may not copy without prior approval.

    The Interesting Difference Between "Exception" and "RuntimeException" (Java)

    Bob Balaban  February 2 2013 06:43:32 PM
    Greetings Geeks!

    I hope everyone who attended Lotusphere IBMConnect '13 had a good time and has returned home safely. I didn't attend (again, I stopped going after the first 17), but I've been hearing that it was pretty good.

    I learned something new about certain types of exceptions in Java programming the other day. Here's the context:
    • I had an Enum class with a few items in it
    • I had a String that came from outside the program that I wanted to convert into an enum'ed constant
    • This was happening inside an existing function where I didn't want to add to the "throws" declaration (because that would cause ripple effects up into the functions that called the function I was modifying)

    Here's my first draft implementation (this isn't the real code, I created a standalone example for ya):

    import
    java.io.*;

    public
    class ExceptionTest
    {
           public enum someEnum
           {
                   firstitem, seconditem, thirditem
           }
           
           public static void main(String [] args)
           {
                   try { func1(args[0]); }
                   catch (IOException ioe) {}
                   
                   try { func2(args[0]); }
                   catch (IOException ioe) {}
           }
           
           public static void func1(String arg) throws IOException
           {
                   someEnum myEnum = null;
                   
                   System.out.println("In func1");
                   if (arg.equals("firstitem"))
                           myEnum = someEnum.firstitem;
                   else if (arg.equals("seconditem"))
                           myEnum = someEnum.seconditem;
                   else if (arg.equals("thirtitem"))
                           myEnum = someEnum.thirditem;
                   else System.out.println("Invalid input: " + arg);
                   
                   if (myEnum != null)
                           System.out.println("myEnum: " + myEnum.name());
           }
    }

    Not too bad, but rather tedious.  Note that myEnum.name() will take the enum's item value and convert it into a String.

    A colleague pointed out to me that the Java Enum class (all "enums" are compiled into instances of the class Enum) has a valueOf() method. You give it a string, it returns the enum item (e.g., someEnum..firstitem). So, it's effectively the reverse of the name() method.

    I noticed from the javadoc that this function can throw an IllegalArgumentException. It'll do that if the string you give it doesn't match one of the enum items. So I changed my "func1" implementation into what I'll show you here as func2():

           public static void func2(String arg) throws IOException
           {
                   someEnum myEnum = null;
                   
                   System.out.println("In func2");
                   try { myEnum = someEnum.valueOf(arg); }
                   catch (IllegalArgumentException iae) {}
                   
                   if (myEnum == null)
                           System.out.println("Invalid input: " + arg);
                   else System.out.println("myEnum: " + myEnum.name());
                   
           }

    Simpler, right? I thought at this point that I had it nailed. But then that same colleague said, "Hey, you know you don't need the try/catch there". I was sure he was wrong (this stuff happens to me all the time). "No, I do need it, because I don't want to add IllegalArgumentException to the function 'throws' list." I was sure that if I took out the try/catch I'd get a compile error saying I needed it.

    Buuuuuuutt noooooooo, I was wrong. And here's what I hadn't realized until then: There are TWO categories of Exceptions. Many classes that extend (inherit from) java.lang.Exception (like IOException, for example), are required to either be declared in a "throws" clause in the function declaration, or "caught" in a try/catch block. The compiler enforces this.

    However, SOME exception classes (such as IllegalArgumentException) extend not java.lang.Exception, but java.lang.RuntimeException (which itself extends Exception). These are special, you don't need to catch them or declare them explicitly. Here's the slimmed down version of func2():

           public static void func2(String arg) throws IOException
           {
                   someEnum myEnum = null;
                   
                   System.out.println("In func2");
                   myEnum = someEnum.valueOf(arg);
                   
                   if (myEnum == null)
                           System.out.println("Invalid input: " + arg);
                   else System.out.println("myEnum: " + myEnum.name());
                   
           }

    No compile problems. AND, if you later add more items to the enum, you don't have to change any of the other code.

    If you run this with a valid input (such as "firstitem"). If you run it with something other than a string that matches one of the enum items, you get this:

    Exception in thread "main" java.lang.IllegalArgumentException: No enum constant ExceptionTest.someEnum.item
           at java.lang.Enum.valueOf(Unknown Source)
           at ExceptionTest$someEnum.valueOf(ExceptionTest.java:1)
           at ExceptionTest.func2(ExceptionTest.java:42)
           at ExceptionTest.main(ExceptionTest.java:15)

    Of course, you still CAN use try/catch here. You might do that if you want to catch the "illegal" argument and re-throw an application-specific Exception, or create a nicer error message. But you don't have to, because derivatives of RuntimeException are treated specially by the Java compiler.

    Now you know!

    Geek ya later!

    Follow me on Twitter @LooseleafLLC
    This article ©Copyright 2013 by Looseleaf Software LLC, all rights reserved. You may link to this page, but may not copy without prior approval.

    "Reflections on Reflecting Light" - Java program

    Bob Balaban  May 9 2012 06:33:45 PM
    Greetings Geeks!

    Today it is my very great pleasure to introduce to you a new guest blogger: my son David. He has graciously allowed me to prevail upon him to write about his recent science fair project, titled "Reflections on Reflecteing Light". That may sound innocuous, but to quote one of my favorite movies, "That's no ordinary rabbit!". David took this project through our local high school's science fair, was invited to the regional fair, and then to the Massachusetts state science and engineering fair, held at MIT. The Java program he wrote is very sophisticated, both in concept and in execution, and David has agreed to post it here.

    David is looking for a software internship for this summer. If you like this sample of his work (and you are in the Boston area), please consider hiring him!  He is a graduating high school senior, and will attend UMass/Amherst in the Fall, majoring in Physics and Computer Science.

    Caveats:

    1) Use the code for anything you like, with appropriate attribution to David Balaban.
    2) If you make any money from this code, you owe some to David.
    3) The entire contents of this page and of the attached code is copyright 2012, Looseleaf Software, Inc. All rights reserved!

    David's email is: david AT Looseleaf.net
    My email is: bbalaban AT gmail

    Here's the abstract:

    The purpose of my project is to determine how distorted an image becomes when it is reflected off of a curved surface and how the distortion changes as the surface becomes more curved. My hypothesis was that parts of the image will move towards the center of valleys while other parts will move away from peaks and move a smaller distance as the surface becomes more curved. To test this hypothesis, I wrote a program that takes an image saved on the computer and converts it to an array of pixels. The program treats each pixel as a beam of light traveling directly towards a mathematically generated curved surface and traces its path as it is reflected. The program ends by reporting statistical information resulting from over one million beams of light and creating a new picture which shows the resulting image from the reflection. My hypothesis was incorrect, because on average the pixels move away from the center of valleys, not towards.

    And here's the code (RAR format): ScienceFair.rar

    Here's an example of one of the images he used as input to the program: Control.jpg

    And here's the distorted result of that same image: Trial1.gif

    Enjoy!

    Geek ya later!

    Happy 5th? Yeah, 5th

    Bob Balaban  April 10 2012 09:11:32 PM
    Greetings Geeks!

    So. March 30, 2007 was my first blog entry. Evidently I missed my own 5th Blanniversary! :-( Better late than never, I suppose. In theory, anyway :-)

    I know I don't post here often, but I do hope that when I do post, it's worth reading. For some people, anyway.

    I'll quote from a nice person who commented on that first post: "energetic,funny,cute--that's what I feel about you from your special explanation about "In Theory".I think you must be very content while writing these words."

    Well, yeah! That does pretty much sum it up. Thanks!

    If you read the original post, you might be interested to know that I'm STILL using that same 7.2 blog template (why change? It works!), and most of the time I'm still using Notes 7, except when I have to do dev work (sit down for beer with me sometime, and I'll tell you why, if you don't already know).

    Any topics anyone wants to hear about from me? Suggestions welcome. I still plan to stick to solid techie topics (GeekStuff), and avoid the fluffy stuff, which you can get anywhere.
    Don't ask for XPages topics, I don't do XPages.

    Thanks to those of you who are still reading after all this time, and thanks to those of you who are newer to this space.

    Geek ya later!

    (Need expert application development architecture/coding help?  Want me to help you invent directory services based on RDBMS? Need some Cloud-fu or some web services? Contact me at: bbalaban, gmail.com)
    Follow me on Twitter @LooseleafLLC
    This article ©Copyright 2012 by Looseleaf Software LLC, all rights reserved. You may link to this page, but may not copy without prior approval.

    "Programming Domino With Java" - Final Flush

    Bob Balaban  January 2 2012 03:56:33 AM
    Happy New Year, Geeks!

    Here's the 7th (and final) installment of the book. Thanks again for all the positive feedback.
    The first installment can be found here
    The 2nd installment is here
    The 3rd is here
    The 4th is here
    The 5th is here
    and the 6th is here

    All of the book content (as is all of the content on this blog) is Copyright 1998 and 2011 by Looseleaf Software, Inc. You may not reproduce or distribute the book's content without permission from me.

    Some Caveats and explanations:

    - This book is now 12 years old. There are lots of things in it that are amusingly dated, even laughable. One example: the absurd emphasis on Java Applets. They died an unlamented death due to bloating a long time ago, but at the time I wrote the book, they were a hot technology.
    - The formatting is not exactly as it first appeared in the book, and some of it is downright awkward. Sorry! The publisher converted the original files to Word for me, perhaps they forgot to select the "high-def" option.
    - The Java package described in the book (lotus.notes) was superseded by lotus.domino in R5 (1999? I think). The methods are all mostly the same. Of course, IBM have added lots more classes and methods than existed when the book was written. Also, the "recycle()" method had not yet been invented in Domino 4.6, so the memory issues that call addresses are not really covered.
    - The figures (screen shots and so on) referred to did not make it into any file format I can deal with, so I had to leave them out. Sorry! The code samples are mostly there, and I'll also post all of the files that were on the CD that came with the original book.

    This Installment

    This hunk is a zip file containing the contents of the CD that was included with the original book.
    Appendix F (previously posted) contains a description of the contents of the CD: Appendix F.pdf

    I have not gone back and checked that the samples still work. If you find that any do not, please let me know.
    The JavaDoc, of course, corresponds to the Notes v4.0 release. "NOI" has come a long way since then, and the whole lotus.notes package was pretty much obsoleted in Notes v5, but they may still be distributing it.

    CD.zip

    Enjoy! Geek ya later

    (Need expert application development architecture/coding help?  Want me to help you invent directory services based on RDBMS? Need some Cloud-fu or some web services? Contact me at: bbalaban, gmail.com)
    Follow me on Twitter @LooseleafLLC
    This article ©Copyright 2012 by Looseleaf Software LLC, all rights reserved. You may link to this page, but may not copy without prior approval.

    "Programming Domino With Java" - Sixth Sip

    Bob Balaban  December 6 2011 11:17:56 AM
    Greetings, Geeks!

    Here's the 6th installment of the book. Thanks again for all the positive feedback.
    The first installment can be found here
    The 2nd installment is here
    The 3rd is here
    The 4th is here
    The 5th is here

    All of the book content (as is all of the content on this blog) is Copyright 1998 and 2011 by Looseleaf Software, Inc. You may not reproduce or distribute the book's content without permission from me.

    Some Caveats and explanations:

    - This book is now 12 years old. There are lots of things in it that are amusingly dated, even laughable. One example: the absurd emphasis on Java Applets. They died an unlamented death due to bloating a long time ago, but at the time I wrote the book, they were a hot technology.
    - The formatting is not exactly as it first appeared in the book, and some of it is downright awkward. Sorry! The publisher converted the original files to Word for me, perhaps they forgot to select the "high-def" option.
    - The Java package described in the book (lotus.notes) was superseded by lotus.domino in R5 (1999? I think). The methods are all mostly the same. Of course, IBM have added lots more classes and methods than existed when the book was written. Also, the "recycle()" method had not yet been invented in Domino 4.6, so the memory issues that call addresses are not really covered.
    - The figures (screen shots and so on) referred to did not make it into any file format I can deal with, so I had to leave them out. Sorry! The code samples are mostly there, and I'll also post all of the files that were on the CD that came with the original book.

    This Installment


    We're done with the main body of text (Chapters 1-14), but there's still more good stuff to post:

    Appendix A "Useful Links and References" Appendix A.pdf

    Appendix B "Notes Object Interface Class Diagram" (yeah, a little out of date now...)
    Appendix B.pdf

    Appendix C "Domino Setup For Writing Java Programs" Appendix C.pdf

    Appendix D "Notes Object Interface Exceptions" Appendix D.pdf

    Appendix E "Creating LSXs" (Note: This was WAY before Lotus released the "LSX Toolkit", known far and wide in song and legend. You can probably still get the toolkit at this site, though I haven't checked lately. It hasn't had a new release in years, and is known to be broken for recent versions of Microsoft Visual Studio)
    Appendix E.pdf

    Appendix F "What's On the CD-ROM" Appendix F.pdf

    Next installment, I'll post the samples and javadoc from the CD

    Enjoy! Geek ya later

    (Need expert application development architecture/coding help?  Want me to help you invent directory services based on RDBMS? Need some Cloud-fu or some web services? Contact me at: bbalaban, gmail.com)
    Follow me on Twitter @LooseleafLLC
    This article ©Copyright 2011 by Looseleaf Software LLC, all rights reserved. You may link to this page, but may not copy without prior approval.

    "Programming Domino With Java" - Fifth Slug

    Bob Balaban  November 28 2011 05:22:21 PM
    Greetings, Geeks!

    Here's the 5th installment of the book. Thanks again for all the positive feedback.
    The first installment can be found here
    The 2nd installment is here
    The 3rd is here
    The 4th is here

    All of the book content (as is all of the content on this blog) is Copyright 1998 and 2011 by Looseleaf Software, Inc. You may not reproduce or distribute the book's content without permission from me.

    Some Caveats and explanations:

    - This book is now 12 years old. There are lots of things in it that are amusingly dated, even laughable. One example: the absurd emphasis on Java Applets. They died an unlamented death due to bloating a long time ago, but at the time I wrote the book, they were a hot technology.
    - The formatting is not exactly as it first appeared in the book, and some of it is downright awkward. Sorry! The publisher converted the original files to Word for me, perhaps they forgot to select the "high-def" option.
    - The Java package described in the book (lotus.notes) was superseded by lotus.domino in R5 (1999? I think). The methods are all mostly the same. Of course, IBM have added lots more classes and methods than existed when the book was written. Also, the "recycle()" method had not yet been invented in Domino 4.6, so the memory issues that call addresses are not really covered.
    - The figures (screen shots and so on) referred to did not make it into any file format I can deal with, so I had to leave them out. Sorry! The code samples are mostly there, and I'll also post all of the files that were on the CD that came with the original book.

    This Installment


    This time I'm posting 3 more chapters:

    Chapter 12: "NOI and Java Beans" (Are they really good for your heart?)
    Chapter 12.pdf

    Chapter 13: "JDBC and NOI"
    Chapter 13.pdf

    Chapter 14: A Look Ahead to Domino 5 (This ought to provide some laughs, eh?)
    Chapter 14.pdf

    Note:
    Chapter 14 is the last real chapter, but there's still plenty more to come. To wit:
    - Appendices A through F
    - Samples, including some javadoc, since I happen to have it anyway

    Release Notes


    Chapter 12: No bugs!
    Chapter 13: No bugs!
    Chapter 14: Also bug-free!

    Enjoy! More soon. Geek ya later

    (Need expert application development architecture/coding help?  Want me to help you invent directory services based on RDBMS? Need some Cloud-fu or some web services? Contact me at: bbalaban, gmail.com)
    Follow me on Twitter @LooseleafLLC
    This article ©Copyright 2011 by Looseleaf Software LLC, all rights reserved. You may link to this page, but may not copy without prior approval.

    "Programming Domino With Java" - Fourth Hit

    Bob Balaban  November 20 2011 01:30:47 PM
    Greetings, Geeks!

    Here's the 4th installment of the book. Thanks again for all the positive feedback.
    The first installment can be found here
    The 2nd installment is here
    The 3rd is here

    All of the book content (as is all of the content on this blog) is Copyright 1998 and 2011 by Looseleaf Software, Inc. You may not reproduce or distribute the book's content without permission from me.

    Some Caveats and explanations:

    - This book is now 12 years old. There are lots of things in it that are amusingly dated, even laughable. One example: the absurd emphasis on Java Applets. They died an unlamented death due to bloating a long time ago, but at the time I wrote the book, they were a hot technology.
    - The formatting is not exactly as it first appeared in the book, and some of it is downright awkward. Sorry! The publisher converted the original files to Word for me, perhaps they forgot to select the "high-def" option.
    - The Java package described in the book (lotus.notes) was superseded by lotus.domino in R5 (1999? I think). The methods are all mostly the same. Of course, IBM have added lots more classes and methods than existed when the book was written. Also, the "recycle()" method had not yet been invented in Domino 4.6, so the memory issues that call addresses are not really covered.
    - The figures (screen shots and so on) referred to did not make it into any file format I can deal with, so I had to leave them out. Sorry! The code samples are mostly there, and I'll also post all of the files that were on the CD that came with the original book.

    This Installment


    This time I'm posting 3 more chapters:

    Chapter 9 (Debugging NOI Agents) - Chapter 09.pdf
    NOTE: When I wrote the book, Eclipse was not yet invented (or at least, widely known). I hadn't yet come up with the now-common "2-Headed Beast" technique of debugging Java agents (Why hasn't IBM created a way to debug agents inside Designer in the 14 years that Java agents have been loose in the world? I don't know, but it's sad). See here for a description of "2-Headed Beast".

    Chapter 10 (Sharing Objects Across Threads) - Chapter 10.pdf

    Chapter 11 (Upgrading Servlets to Agents) - Chapter 11.pdf

    Release Notes


    Chapter 9: No bugs!

    Chapter 10: No bugs!

    Chapter 11: No bugs!

    Enjoy! More soon. Geek ya later

    (Need expert application development architecture/coding help?  Want me to help you invent directory services based on RDBMS? Need some Cloud-fu or some web services? Contact me at: bbalaban, gmail.com)
    Follow me on Twitter @LooseleafLLC
    This article ©Copyright 2011 by Looseleaf Software LLC, all rights reserved. You may link to this page, but may not copy without prior approval.

    "Programming Domino With Java" - Third Gulp

    Bob Balaban  November 14 2011 06:28:59 PM
    Greetings, Geeks!

    Here's the third installment of the book. Thanks again for all the positive feedback.
    The first installment can be found here
    The 2nd installment is here

    All of the book content (as is all of the content on this blog) is Copyright 1998 and 2011 by Looseleaf Software, Inc. You may not reproduce or distribute the book's content without permission from me.

    Some Caveats and explanations:

    - This book is now 12 years old. There are lots of things in it that are amusingly dated, even laughable. One example: the absurd emphasis on Java Applets. They died an unlamented death due to bloating a long time ago, but at the time I wrote the book, they were a hot technology.
    - The formatting is not exactly as it first appeared in the book, and some of it is downright awkward. Sorry! The publisher converted the original files to Word for me, perhaps they forgot to select the "high-def" option.
    - The Java package described in the book (lotus.notes) was superseded by lotus.domino in R5 (1999? I think). The methods are all mostly the same. Of course, IBM have added lots more classes and methods than existed when the book was written. Also, the "recycle()" method had not yet been invented in Domino 4.6, so the memory issues that call addresses are not really covered.
    - The figures (screen shots and so on) referred to did not make it into any file format I can deal with, so I had to leave them out. Sorry! The code samples are mostly there, and I'll also post all of the files that were on the CD that came with the original book.

    This Installment


    I'm including 3 chapters in this post:

    Chapter 6 (NOI Part 5): Chapter 06.pdf

    Chapter 7 (Writing NOI Applications): Chapter 07.pdf

    Chapter 8 (Writing NOI Agents): Chapter 08.pdf

    Release Notes


    Chapter 6, Page 195. Description of Registration.addUserProfile() mistakenly refers to Database.createProfileDocument(). Should be setProfileDocument()

    Chapter 7, no bugs!

    Chapter 8, Page 265. Listing 8.3 ("Waiting for Child Threads, Ex83Multi.java). Sigh. This code has a major race condition in it that I didn't catch until after the book was out. Basically, the problem is that all of the threads could finish before you get to the logic that tests to see if any of them are alive. There's a better and much more robust pattern for doing this stuff that I could write a separate article about, if there's interest.

    Enjoy! More soon. Geek ya later

    (Need expert application development architecture/coding help?  Want me to help you invent directory services based on RDBMS? Need some Cloud-fu or some web services? Contact me at: bbalaban, gmail.com)
    Follow me on Twitter @LooseleafLLC
    This article ©Copyright 2011 by Looseleaf Software LLC, all rights reserved. You may link to this page, but may not copy without prior approval.

    "Programming Domino With Java": Chunk the Second

    Bob Balaban  November 9 2011 04:28:19 PM
    Greetings, Geeks!

    Here's the second installment of the book. Thanks again for all the positive feedback.
    The first installment can be found here

    All of the book content (as is all of the content on this blog) is Copyright 1998 and 2011 by Looseleaf Software, Inc. You may not reproduce or distribute the book's content without permission from me.

    Some Caveats and explanations:

      - This book is now 12 years old. There are lots of things in it that are amusingly dated, even laughable. One example: the absurd emphasis on Java Applets. They died an unlamented death due to bloating a long time ago, but at the time I wrote the book, they were a hot technology.
      - The formatting is not exactly as it first appeared in the book, and some of it is downright awkward. Sorry! The publisher converted the original files to Word for me, perhaps they forgot to select the "high-def" option.
      - The Java package described in the book (lotus.notes) was superseded by lotus.domino in R5 (1999? I think). The methods are all mostly the same. Of course, IBM have added lots more classes and methods than existed when the book was written. Also, the "recycle()" method had not yet been invented in Domino 4.6, so the memory issues that call addresses are not really covered.
      - The figures (screen shots and so on) referred to did not make it into any file format I can deal with, so I had to leave them out. Sorry! The code samples are mostly there, and I'll also post all of the files that were on the CD that came with the original book.

    This Installment


    I'm including 3 chapters in this post:

    Chapter 3 (NOI Part 2) -- was supposed to be in the previous posting, but ooops. Sorry: Chapter 03.pdf

    Chapter 4 (NOI Part 3): Chapter 04.pdf

    Chapter 5 ( Yes! You guessed it...NOI Part 4): Chapter 05.pdf

    Don't worry, the chapter titles get a little more inventive starting with Chapter 7.

    Release Notes


    Chapter 3:
    Page 98, All of the "Item.appendXXX" method names should have capitalized "Value"

    Page 113, discussion of "auto-update", it describes how you can use getNextDocument(), etc. "That'll work okay". It won't work ok, it'll potentially cause an infinite loop. Ooops.

    Page 117, Listing 3.6, the "for" loop starts an index at 0, should be 1. Same for the loop on Page 118 as well.

    Page 119, mentions a property on View named "IsHierarchical". There is no such property (or at least, there wasn't in 4.6)

    Chapter 4:
    No bugs!

    Chapter 5:
    No bugs!

    Enjoy! More soon. Geek ya later

    (Need expert application development architecture/coding help?  Want me to help you invent directory services based on RDBMS? Need some Cloud-fu or some web services? Contact me at: bbalaban, gmail.com)
    Follow me on Twitter @LooseleafLLC
    This article ©Copyright 2011 by Looseleaf Software LLC, all rights reserved. You may link to this page, but may not copy without prior approval.

    "Programming Domino With Java" - First Installment

    Bob Balaban  November 2 2011 05:50:15 PM
    Greetings, Geeks!

    Here's the first installment of the book. Thanks again for all the positive feedback.

    All of the book content (as is all of the content on this blog) is Copyright 1998 and 2011 by Looseleaf Software, Inc. You may not reproduce or distribute the book's content without permission from me.

    Some Caveats and explanations:

        - This book is now 12 years old. There are lots of things in it that are amusingly dated, even laughable. One example: the absurd emphasis on Java Applets. They died an unlamented death due to bloating a long time ago, but at the time I wrote the book, they were a hot technology.
        - The formatting is not exactly as it first appeared in the book, and some of it is downright awkward. Sorry! The publisher converted the original files to Word for me, perhaps they forgot to select the "high-def" option.
        - The Java package described in the book (lotus.notes) was superseded by lotus.domino in R5 (1999? I think). The methods are all mostly the same. Of course, IBM have added lots more classes and methods than existed when the book was written. Also, the "recycle()" method had not yet been invented in Domino 4.6, so the memory issues that call addresses are not really covered.
        - The figures (screen shots and so on) referred to did not make it into any file format I can deal with, so I had to leave them out. Sorry! The code samples are mostly there, and I'll also post all of the files that were on the CD that came with the original book.

    This Installment

    I'm including the Dedication/Preface, and Chapters 1 ("Programmability Overview"), 2 ("NOI Part 1") and 3 ("NOI Part 2"). "NOI" is "Notes Object Interface", what we called the "back-end classes" in the day.

    Preface/etc.: ded_ack_pref.pdf

    Chapter 1: Chapter 01.pdf

    Chapter 2: Chapter 02.pdf

    Release Notes


    Chapter 2:
    Page 15, "Refer to Appendix A for a diagram...", should be "Appendix B"

    Page 33, Listing 2.2, Missing closing curly-brace "}" right before the "catch" statement

    Page 58, description of Database.createCopy() method, should mention that the method does not copy data, only the design of the db

    Chapter 3:
    Page 98, All of the "Item.appendXXX" method names should have capitalized "Value"

    Page 113, discussion of "auto-update", it describes how you can use getNextDocument(), etc. "That'll work okay". It won't work ok, it'll potentially cause an infinite loop. Ooops.

    Page 117, Listing 3.6, the "for" loop starts an index at 0, should be 1. Same for the loop on Page 118 as well.

    Page 119, mentions a property on View named "IsHierarchical". There is no such property (or at least, there wasn't in 4.6)

    Enjoy! More soon.

    (Need expert application development architecture/coding help?  Want me to help you invent directory services based on RDBMS? Need some Cloud-fu or some web services? Contact me at: bbalaban, gmail.com)
    Follow me on Twitter @LooseleafLLC
    This article ©Copyright 2011 by Looseleaf Software LLC, all rights reserved. You may link to this page, but may not copy without prior approval.

    Anyone interested in me posting my 1998 book?

    Bob Balaban  October 29 2011 09:34:15 AM
    Greetings, Geeks!

    In 1998 I published a book titled "Programming Domino 4.6 With Java" (see the Amazon page here). It did fairly well, but of course it's a bit dated now, and it went out of print in 2000.

    While you can apparently get a used copy for $0.59 (plus shipping), I was thinking I might post the PDF version of the whole thing here on my blog (the rights to the book reverted to me when the publisher declared it out of print, so it's legal). There are bugs in there, which I suppose I could publish "release notes" for, too. I think it's still the best detailed description of the Java "back-end classes" for N/D, as that library existed in October, 1997.

    Any interest? If you'd like to see it, post a comment here. If you wouldn't like to see it, post a comment here.

    Geek ya later!

    Check out CouchConf in New York, October 24

    Bob Balaban  October 10 2011 05:59:10 PM
    CouchDb has gained notice in recent years as an innovator in the "NoSQL" data management space. CouchDb was invented by Damien Katz (http://damienkatz.net/), a former colleague of mine from the old days at Iris Associates. Couch is now open-sourced (via Apache, I think) and Damien's new company, CouchBase (http://www.couchbase.com/), helps organizations use it effectively to solve all sorts of business (and other) problems.
    If you're in the New York City area on October 24th, check it out.

    Geek-O-Terica 16: Easy conversion of Notes documents to MIME format (Part 2)

    Bob Balaban  April 4 2011 05:45:00 AM
    Greetings, Geeks!

    Recently I posted some sample code showing you how to convert Notes documents to MIME format on disk, using the Notes Java APIs. Unfortunately, if you need to do this kind of conversion using some other platform (such as .net), the job is a bit harder. A key method on the Document class (doc.convertToMIME()) is missing in the COM classes for Notes. Why? No idea, someone should ask Lotus about that. Probably has something to do with fear (but that's just speculation on my part).

    No worries, though. the convertToMIME() method uses public C API calls to do its work, so we can do the same from a .net program. For starters, see my blog post on calling C API from C# (c-sharp) programs, here. That post talks about the basic techniques and syntax for setting up any kind of call-out from C# to C, so I won't repeat that here (the idea is just about the same if you're using vb). Here's a c-sharp file that provides a bunch of wrappers for Notes C API calls, bundled together in a class called NotesEntriess.  NotesEntries.cs

    The tedious bit about doing MIME conversion for a .net program is that there are several C calls you have to make for the 1 Java/LotusScript call. The tricky part is that, to do it without having to do everything at the C API level, you want to save typing by leveraging the COM classes, and only use the NotesEntries wrappers when you have to. The problem is that the COM classes do not expose the in-memory "handle" for a NotesDocument instance -- you can only get the Note ID -- while the C API calls require the handle for most things.

    So you'll see in the sample program "BlogMIME.cs" (BlogMIME.cs) that the first part of the work (converting a document to MIME format in memory) is done with C API wrappers (after using "regular" COM classes to access the NSF and find the document in the first place, of course). I could have continued to use the C API to iterate over MIMEParts in the converted document, force Base64 encoding, and write out the results, but it's really much easier to do all that using COM classes. Unfortunately, there's no way to take the NOTEHANDLE that I get using the C API and use it to get a NotesDocument COM object. I had to save() the document back to disk, get the Note ID, and use that to "get" the document again via COM. There's a slight performance hit for the extra save, but it was worth it in this case.

    You'll notice that the c# code that actually writes out the converted MIME document to disk is almost a line-for-line translation of the Java code I posted earlier. That's possible because the Notes COM classes are almost identical (on purpose) to the Java and LotusScript interfaces. The only reason we have to get tricky with using C API wrappers is that the Document.convertToMIME() function is missing in the COM interface.

    There are some other nice (reusable) features of the c# code, such as mapping various C constants to c# syntax, and so on. So, take the code, use it as a source of techniques for doing this kind of integration.  Enjoy!

    Geek ya later.

    (Need expert application development architecture/coding help?  Want me to help you invent directory services based on RDBMS? Need some Cloud-fu or some web services? Contact me at: bbalaban, gmail.com)
    Follow me on Twitter @LooseleafLLC
    This article ©Copyright 2011 by Looseleaf Software LLC, all rights reserved. You may link to this page, but may not copy without prior approval.

    Geek-O-Terica 15: Easy conversion of Notes documents to MIME format (Part 1)

    Bob Balaban  March 21 2011 04:00:00 AM
    Greetings, Geeks!

    MIME is a data format that has become central to transmission of email over the Internet. The nice thing about it is that everyone uses it for mail interchange, and that it's standard. The Domino server converts incoming MIME-formatted messages into Notes documents, and outgoing Notes email documents into MIME formats. As of (I think) Notes v6, you can specify that you want incoming MIME messages to remain in their native format within the NSF database. In these cases, the Notes client will automatically convert any document that resides in MIME format to "regular" Notes rich text document format when you open it in the client UI.

    What does MIME format look like? It can get complicated, but the easiest way to think of it is as a sectioned box, with each compartment within the box holding data in a specified format. So, plain text is just a plain-text section. "Rich text" is usually represented as HTML, with embedded "pointers" to other sections containing embedded objects, such as images or attachments. Other data, such as file attachments, reside in their own sections, with their own "headers" specifying size, encoding (e.g., base-64) and format (e.g., JPEG or GIF). The different sections in the MIME file are separated by "boundaries", essentially a unique string. There's much more to it, of course, but these are the basics.

    What if you want to write script (LotusScript, Java, other) to programmatically convert Notes documents to MIME format? If you're using a recent (v8.5x) version of Notes or Domino, then most of the work is done for you with new methods in the back-end classes. This functionality is, of course, based on entry points in the Notes C API. If you're not using LotusScript or Java, you can accomplish MIME translation with  a C or C++ program using these entry points, or, even easier, use the COM classses. I'll discuss how to do MIME conversion using the C and COM APIs in Part Deux of this post.

    Here's a basic Java program showing the essential techniques for conversion. I'm leaving out all the surrounding code for acquiring Document objects, preparing FileOutputStreams, and so on. There is only one slightly tricky thing about this program, which we'll get to after this first section.

    Session session = NotesFactory.createSession();
    // turn off automatic mime conversion on document open
    // if doc is already in MIME, leave it so
    session.setConvertMIME(false);
    Document doc = .... // get document somewhere
    // kill any $KeepPrivate items
    doc.removeItem("$KeepPrivate");
    doc.convertToMIME(lotus.domino.Document.CVT_RT_TO_HTML, 0);   // note: Designer doc has wrong spelling
    WriteOutputMIME(doc);

    So far, so good. We suppress automatic conversion on document open, to save work (if the document is already in MIME format, we can skip the convert step and just write it out). If the "$KeepPrivate" item is present in the document, conversion will fail, so we remove that. Then all we do is call the Document.convertToMIME() method, specifying that we want rich text converted to HTML.

    After the convert call, the document in memory is now a sequence of items containing MIME headers, and a (possibly multi-part) body representing the rich text body of the original document, plus any attachments it contains. We can (almost) proceed to iterate over these items and write them out to disk (or wherever).

    I say "almost", though, because there's a glitch in the conversion code deep underneath the C API layer: it does not automatically convert attachment contents to a base-64 encoding (even though the API documentation says it will) - it leaves them in binary format, which cannot be written to disk. So, we have to look for those items, and force them to be converted to base-64 text. This next section of Java code for the WriteOutputMIME() functions shows how to do that. Again, I've pared the code down to the essential bits:

          private void WriteOutputMIME(Document doc, File outDir)
          throws Exception
    {
          File outFile = null;
          MIMEEntity mE = null;
          MIMEEntity mChild = null;
          String contenttype = null;
          String headers = null;
          String content = null;
          String preamble = null;
          int encoding;
          FileWriter output = null;
          String noteid = doc.getNoteID();
          int index;
         
          // access document as mime parts
          mE = doc.getMIMEEntity("Body");
          outFile = new File(outDir, noteid + ".eml");
          output = new FileWriter(outFile);
         
          try {
                  contenttype = mE.getContentType();
                  headers = mE.getHeaders();
                  encoding = mE.getEncoding();
                 
                  // message envelope. If no MIME-version header, add one
                  index = headers.indexOf("MIME-Version:");
                  if (index < 0)
                          output.write("MIME-Version: 1.0\n");
                  output.write(headers);
                 
                  // for multipart, usually no main-msg content
                  content = mE.getContentAsText();
                  if (content != null && content.trim().length() > 0)
                          {
                          output.write(content);
                          output.write("\n");
                          }

              // For multipart, examine each child entity,
              // re-code to base64 if necessary                
                  if (contenttype.startsWith("multipart"))
                          {
                          preamble = mE.getPreamble();
                          mChild = mE.getFirstChildEntity();
                          while (mChild != null)
                                  {
                                  headers = mChild.getHeaders();
                                  encoding = mChild.getEncoding();
                                 
                                  // convert binary parts to base-64
                                  if (encoding == MIMEEntity.ENC_IDENTITY_BINARY)
                                          {
                                          mChild.encodeContent(MIMEEntity.ENC_BASE64);
                                          headers = mChild.getHeaders(); // get again, because changed
                                          }
                                 
                                  preamble = mChild.getPreamble();
                                  content = mChild.getBoundaryStart();
                                  output.write(content);
                                  if (!content.endsWith("\n"))
                                          output.write("\n");
                                  output.write(headers);
                                  output.write("\n");
                                 
                                  content = mChild.getContentAsText();
                                  if (content != null && content.length() > 0)
                                          output.write(content);
                                  output.write(mChild.getBoundaryEnd());
                                 
                                  mChild = mChild.getNextSibling();
                                  } // end while
                          } // end multipart
                 
                  // end of main envelope
                  output.write(mE.getBoundaryEnd());
                  }
          finally {
                          if (output != null)
                                  output.close();
                          }
         
    } // end WriteOutptuMIME

    So, a little tricky, but not too bad. You have to get the boundaries right, as well as the line breaks. Otherwise, it's really just copying stuff out to disk. Remember that the message has some overall headers (mE.getHeaders()), and each child entity has its own header section as well, describing what's in that chunk of data. When we re-code an entity from binary format to base-64 format, we need to re-read the entity headers, because they'll reflect that change.

    A final comment about HTML conversion: it theoretically existed back in R5 (you know what they say about "in theory"...), but it didn't start working well for real until v7.03. And it has been improving ever since, so the later the version of the product you have, the better off you'll be.

    In my next blog post (part deux), I'll show you how to adapt this basic code for the Notes COM classes, where (for some stupid reason) the Document.convertToMIME() function does not exist). We will not be thwarted! I'll show you how to use the Notes C API from a C-sharp program to do the MIME conversion.

    Happy coding! Geek ya later!

    (Need expert application development architecture/coding help?  Want me to help you invent directory services based on RDBMS? Need some Cloud-fu or some web services? Contact me at: bbalaban, gmail.com)
    Follow me on Twitter @LooseleafLLC
    This article ©Copyright 2011 by Looseleaf Software LLC, all rights reserved. You may link to this page, but may not copy without prior approval.