Author:

TimEvil Genius specializing in OS's, special hardware and other digital esoterica with a bent for Java.

The Underappreciated Raspberry

Posted by – March 23, 2013

The Raspberry Pi B version is one of the most popular hacker toys of the day and with good reason. Although it’s not the first sub-miniature single-board computer, it’s the first one whose price, performance, features and power make it an acceptable substitute for a “real” desktop computer.

But there’s another Raspberry Pi as well. Ironically, the “A” model came out after the “B” model. Unlike the “B”, it lacks a few things. Only one USB port and no on-board ethernet, for example.

But before you dismiss it as not worth the $10 lower price, here are some things to consider:

1. The “A” model pulls less power, since it doesn’t have to support those missing components. This is especially important if you want to run the unit off batteries or solar cells.

2. The ethernet controller on the B is actually just a third USB port with an on-board USB-ethernet adapter. If I need to add ethernet to an “A” board, I have a USB ethernet dongle sitting on the shelf right next to me. I originally bought it to network-enable an old laptop.

3. Some people prefer NOT to have critical machines on the Internet. Why pay for hardware you don’t want to use? Plus these days, a lot of people skip the wiring and use WiFi adapters. There are a number of WiFi dongles that will plug into the USB port. Why pay extra for a jack you don’t need? Or for power to support it?

4. Enough about networking, though, consider USB. For some people 2 USB ports are more than they need. So the single port on the “A” system may be sufficient or even surplus. Conversely, for some people, 2 ports are not enough. And/or they need powered ports with more power than the Raspberry Pi itself supplies. USB expansion hubs, both powered and un-powered have been around a long time and are easy to come by.

So we have 2 choices. A good general-purpose platform and a cheaper basic platform. Both expandable, both economical in their own ways.

DBUnit and CSV reference data

Posted by – December 31, 2012

The CSV capabilities of dbUnit are under-documented. Here’s the results of some pain, suffering and debug tracing:

The CSV files are expected to be one-per-table. The tablename is part of the filename, thus: “table1.csv”. Format is the usual, with the first row containing the column names and subsequent rows containing data. It is possible to customize the delimiters and separators, but the defaults work with bog-standard CSV. One possible reason to override is to allow use with pipe-separated format files.

Here’s some code to snapshot an SQL query out to CSV for use as a later test reference (or whatever).

Connection con =
DataSourceUtils.getConnection(dataSource);
IDatabaseConnection dbUnitCon =
new DatabaseConnection(con, "MYDB");

ITable actualTable =
dbUnitCon.createQueryTable(
"SNAPTABLE",
"SELECT * FROM QTABLE "
+ " WHERE INK1='GLORP'"
+ " AND INK_ID in('ABEND001', 'AAA', '07CSI')");

// Take reference snapshot:
IDataSet ds1 = new DefaultDataSet(actualTable);
CsvDataSetWriter.write(ds1, new File("/home/timh/csvdir"));

dbUnit will create csvdir, if needed and output 2 files. The SNAPTABLE.csv file and a file named “table-ordering.txt”.


To load SNAPTABLE for use in validating the results of a test:

// Load expected data from CSV dataset
CsvDataFileLoader ldr = new CsvDataFileLoader();
// NOTE: terminal "/" on URL is MANDATORY!!!
IDataSet expectedDataSet =
ldr.load("/testdata/snapshots/");
ITable expectedTable =
expectedDataSet.getTable("SNAPTABLE");

// Assert actual database table match expected table
Assertion.assertEquals(expectedTable, actualTable);

Note that while you can specify case-insensitivity on table names (it’s the default), the case of the SNAPTABLE.csv file and the SNAPTABLE entry in table-ordering.txt must match – at least on case-sensitive OS’s. And it’s good practice regardless. Also note that table-ordering.txt can contain multiple table names. Comma-separated on a single line, I think. If not, try one tablename per line.

Finally, note that the error exception for the comparison assert counts line numbers off by 2. It doesn’t take the column-name row into account, and it starts counting from 0, instead of the more usual case (for databases) of counting starting at 1.

Gourmet Recipe Manager problems under recent Fedora releases

Posted by – November 8, 2012

The Gourmet Recipe Manager program is a very useful way to store and find recipes, but it has been essentially useless since about Fedora 11 (give or take).

The problem is that this app uses an SQLite database to keep its recipes and accesses the database using SQLAlchemy. Version 0.7 is seriously broken relative to Gourmet.

The cure, once you know it, is relatively easy – at least as long as you don’t have any other apps depending on SQLAlchemy (and I didn’t). First, check to see if you do:

rpm -q --whatrequires python-sqlalchemy

If gourmet is your only dependent (or you don’t care/feel brave), remove the 0.7 sqlalchemy package by brute force:

rpm --erase --nodep python-sqlalchemy

Download one of the 0.6 versions of sqlalchemy. If you have a 64-bit system, be sure to get the 64-bit RPM, which includes the 32-bit version.

Install the downloaded sqlalchemy RPM

rpm -ivh python-sqlalchemy-0.6.xxxxxx.rpm

Fire up gourmet. One of the easiest ways to see if it works is just to type a search. If it returns search results, you’re OK!

A Utility Program for Cataloging Ebooks

Posted by – April 24, 2012

My books are among my greatest assets. So much so that finding room to store them all has long been a problem. So the emergence of ebook readers has been a big help to me.

However, to be of true value, certain aspects of the “dead tree” format must carry over and one of the most important ones is that when I buy a book, I own the book. I don’t “buy a license” for a book. Especially when you consider that ebooks typically sell for about the same price as their physical counterparts.

In order for a book to be truly “buyable”, however, certain principles must apply. On my side, that means that I treat it just like I would a real book and don’t go giving away freebie copies to my friends. Ideally, I could sell “used” ebooks or give them away, but that’s an idea whose time has yet to come.

On the seller’s side, that means a minimum of intrusiveness. I have to be able to read the book without being in direct contact with its “Big Brother” server out on the Internet. I will not tolerate sellers who yank back or alter books without my express permission. No “1984″s down on the Animal Farm. And my library shouldn’t “burn down to the ground” if the vendor goes under a la Borders Books.

The Barnes&Noble system generally meets those criteria. There’s DRM, but it’s (presently) “locks for honest people”, which I can live with. If for any reason, B&N shuts down their servers and exits the business, I have local backups and the means to keep reading them. My means of obtaining local backups has been tampered with on the Nook Tablet, which “hides” the purchased books from the USB storage device, and that’s a feature I hope that they’ll reconsider, since I’ll be keeping it in mind as I make future purchases, but for now, I can deal with it, if not appreciate it.

However, once I’ve made my local backups, I needed a way to be able to browse the local library. The B&N ebook filenames are based on their ISBN numbers, which makes them unique, but hard to locate. So I wrote this little app to be able to scan epub-format books and list their names and authors in a format that’s convenient for spreadsheets and database to take in.

It also determines what encryption algorithm provides DRM. If I scan a library and see that someone’s using DRM that I can’t decode, that’s a red flag and WILL affect both my present-day opinion of the publisher (as in what I recommend to others) AND future purchases.

My sincere thanks to publishers such as O’Reilly and Associates, Baen Books, and others who have been brave enough to forgo DRM altogether. You have placed your trust in my honesty and I will uphold it. Late update: TOR has joined the no-DRM club according to an announcement I just heard today. I’ve helped them kill a few trees over the years!

Catalog application downloads

My ePub catalog utility is a Java application located at http://www.mousetech.com/ebooks-catalog-1.0.jar. To use it:


java -jar ebooks-catalog-1.0.jar f1.epub [f2.epub f3.epub ...]

Where "f1.epub", "f2.epub" and so forth are the names of epub files and/or directories containing epubs. This app doesn't descend to lower directory levels, so if you're running Linux, use the "find" command if you want that.

You can also build this app from source code using Maven. Just download the following file, cd to the directory containing pom.xml and do a "mvn package" command. The source is at http://www.mousetech.com/ebooks-catalog.zip.

Both source and executable may be freely redistributed as long as you don't charge for it or take away credit for my efforts.

JSF2 Annotations Ignored

Posted by – March 20, 2012

I couldn’t figure out why when I tried to retro-fit an old JSF project for JSF2 annotations the annotations weren’t being processed and the managed beans weren’t being instantiated.

Duh. The JSF2 annotation processor defers to faces-config.xml. My faces-config still said JSF 1.2 in the faces-config element and related xmlns attributes.

On a related note, annotations are only processed by default in the WAR WEB-INF/classes directory. If including JARs in WEB-INF/lib, each jar containing managed beans need a META-INF/faces-config.xml. Doesn’t have to have anything in it, but if it isn’t there, annotations won’t process.

The Horrors of OpenOffice Macro Programming

Posted by – March 19, 2012

I love OpenOffice as a user. I have absolutely no envy for (ahem) That Other Product. In truth, just about every new MS-Office feature added since 1997 has been completely meaningless to me.

I have been manipulating OpenOffice/LibreOffice/StarOffice in various creative docs for some years now, but mostly by running XML processes against the ODF files. While XSLT is a royal pain, it beats the alternatives, and the ODT format is straightforward enough.

Recently, however, I’ve had a need to do some heavy reformatting of spreadsheets. They get generated as CSV files, imported, formatted, and various formulas plugged into them. I got tired of doing this by hand, so I decided it was time to automate the process.

¡Ay, Caramba! What a nightmare!

On the one hand, there are all sorts of different ways to script OpenOffice. Java, Python, beanshell, and Basic. Two different kinds of Basic.

If you use the macro recorder, it captures scripts using one programming interface. However, when you write scripts by hand, you would normally use a completely different, less-awkward interface. Even if you wanted to use the capture API, trying to figure out what the various functions and features are makes it a rough proposition, since almost everything is basically set up an array of parameters and passing it to an execute function.

The simpler, hand-coded BASIC API, however, isn’t much better. Unlike the capture API, which maps onto the document model objects directly, the BASIC API attempts to provide convenience methods and properties. Unfortunately, some of them are pretty darned inconvenient, and as awful as the access documentation is, at least the low-level stuff is documented. Lots of luck with the high-level stuff.

I’ve heard the excuse made that the reason MS has so much better Office programming documentation is that they have the force of a Fortune 50 company behind them, but that rings hollow. OpenOffice after all was owned by Sun, then Oracle, and the community of OOffice users is pretty large. There really isn’t an excuse. About the best I’ve seen for how to program OpenOffice is a book that’s out of print.

So, while I myself don’t have the resources to remedy this situation, I’m putting together something that will at least work as a “cheat sheet” for OOCalc macro programming. Here it is: OpenOffice Calc Macro CheatSheet

  • Comments Closed

The Dark Side of the Nook

Posted by – February 15, 2012

I knew that people were unhappy with the Nook Tablet because it reserved a lot of memory for itself, but I hadn’t realized how far the rot has truly run.

One of the reasons why this unit appealed to me was that I expected it to continue the open-ness of the Nook Color, its predecessor. Sadly, this is not so. The only way to root a Nook Tablet is to wipe it back to factory settings. While on the whole, I like the tablet’s native OS, the B&N app store is pretty thin as far as some of my favorite Android apps go, and I’m displeased that I have been blocked from doing anything about that.

More serious, however, is what they’ve done to the books themselves. Side-loaded books are second-class citizens. B&N purchases are completely hidden from side-loading access. And therefore, the only backup mechanism is to re-retrieve them from the B&N servers.

When I buy a book, I expect that I’ve bought the book. An attractive feature of the Nook was that in case B&N ever bail from the business or a superior reader came along, I could decrypt and read my books anytime I wanted to on other platforms and not have them simply evaporate as some of the music services did. With the Nook tablet, this isn’t true anymore.

If I wanted a platform where other people controlled everything I did, I’d get an iPad.

  • Category: Android
  • Comments Closed

RichFaces “columns” tag doesn’t display columns

Posted by – December 2, 2011

The RichFaces manual show this example on using the “columns” tag:

<rich:dataTable value="#{capitalsBean.capitals}" var="cap">
<rich:columns value="#{capitalsBean.labels}" var="col" index="index">

<h:outputText value="#{cap[index]}" />

</rich:columns>

</rich:dataTable>

There is no corresponding sample Java code.

That’s very unfortunate, since in the absence of any better documentation, the natural thing to expect is that “capitalBeans.labels” would be a DataModel object, just as it is for the table itself. And it isn’t.

The model for columns is a simple ordered collection, such as a List.

DB2: SQL2024N The utility encountered an I/O error “2232352780″ while accessing the file type “.BRG”.

Posted by – October 28, 2011

Short answer: I got this when attempting to restore a DB2 backup where the backup file and restore log directory were on a full disk.

Fix: move the backup to somewhere else. That will free up enough space.

JPA and overlapping complex keys

Posted by – June 29, 2011

If at all possible, you should avoid setting up databases with complex keys (or compound keys, as they are sometimes known). It makes life a whole lot more complex, and in a world where everyone already says you’re taking too long because “All You Have To Do Is…”, complex isn’t a good thing.

Sometimes, however, there’s just no choice.

I have one app that has a table with 2 complex-key relationships. The table’s primary key is (idA, idB) and there’s a foreign key reference to another table item with a key of (idA, idC). The table’s key is an embedded object of type “table1Id” and the foreign reference is a lazy-load “table2″ object.

The full details are here.