... until the collector arrives ...

This "blog" is really just a scratchpad of mine. There is not much of general interest here. Most of the content is scribbled down "live" as I discover things I want to remember. I rarely go back to correct mistakes in older entries. You have been warned :)


BIRT Support Site

BIRT Exchange is a new site offering BIRT-related support.

Windows Font-Size Scales Images

If you change your Windows display driver to use large fonts, images may also be scaled -- at least in IE.  I found a situation where a graphic in an embedded IE instance looked awful.  It was larger than expected, and had been scaled with the resulting jaggies.  It turned out to be due to selecting large fonts.  Note that not all applications seemed to be affected this way, but IE7 definitely was.  The display driver in question came from ATI.

BIRT Aggregate Functions

BIRT provides a number of aggregation functions, such as Total.sum() that can be called from within Javascript expressions.  But be aware that these so-called "functions" are actually macros, and are expanded by BIRT prior to execution by the Javascript engine.  The means that they can only appear at the top level of a BIRT data field expression and similar contexts.  They cannot be used in normal Javascript functions or any other non-top-level context.

BIRT Report Data Sources

Here is a code snippet that will replace the design-time connection parameters in all of the ODA/JDBC data sources that use a particular driver:

private void fixupDesignTimeJdbcDataSources(ReportDesignHandle reportDesignHandle) {
    String jdbcDriver = "my.driver.Class";
    String jdbcUrl = "jdbc:mynewurl";
    String jdbcUser = "myuserid";
    String jdbcPassword = "mypassword";
    for (Iterator<?> d = reportDesignHandle.getDataSources().iterator(); d.hasNext();) {
        Object dataSource = d.next();
        if (dataSource instanceof OdaDataSourceHandle) {
            OdaDataSourceHandle odaDataSource = (OdaDataSourceHandle) dataSource;
            if (ODA_JDBC_EXTENSION_ID.equals(odaDataSource.getExtensionID())
                    && jdbcDriver.equals(odaDataSource.getProperty(ODA_DRIVER_CLASS))
                    && null != odaDataSource.getProperty(ODA_URL)) {
                try {
                    odaDataSource.setProperty(ODA_URL, jdbcUrl);
                    odaDataSource.setProperty(ODA_USER, jdbcUser);
                    odaDataSource.setProperty(ODA_PASSWORD, jdbcPassword);
                } catch (SemanticException ex) {
                    throw new RuntimeException(ex);

private static final String ODA_JDBC_EXTENSION_ID = "org.eclipse.birt.report.data.oda.jdbc"; //$NON-NLS-1$
private static final String ODA_DRIVER_CLASS = "odaDriverClass"; //$NON-NLS-1$
private static final String ODA_URL = "odaURL"; //$NON-NLS-1$
private static final String ODA_USER = "odaUser"; //$NON-NLS-1$
private static final String ODA_PASSWORD = "odaPassword"; //$NON-NLS-1$

BIRT Life-cycle Summary

The Eclipse site has a nice article summarizing the BIRT Report Scripting life-cycle.

Dynamic Chart Labelling in BIRT

Here is an example script that can be attached to a BIRT chart object in order to change the labels on the chart dynamically:


function beforeDrawAxisTitle(axis, label, icsc)
    var title = label.caption.value;
    if ("" == title) {
        if (axis.orientation === Orientation.get(Orientation.HORIZONTAL)) {
            label.caption.value = ReportUtilities.formatLongDate(getParameterValue("fromDate"))
                + " to " + ReportUtilities.formatLongDate(getParameterValue("toDate"));
        } else {
            label.caption.value = getParameterValue("currencyDesc");

function beforeRendering(gcs, icsc)
    var chart = gcs.chartModel;
    chart.title.label.caption.value = getParameterValue("reportingPeriodDesc") + " Capital Spending";


CruiseControl vs Subversion

When CruiseControl attempts to determine the modification set using Subversion, it may quietly fail.  'Quietly' in the sense that the build will be reported as a success.  However, if you check the CruiseControl log, a nasty Subversion exception will be reported even though the build did not fail:

2007-09-14 23:40:28,319 [Thread-5128] ERROR SVN - Error executing svn log command svn log --non-interactive --xml -v -r {2007-09-14T21:32:04Z}:{2007-09-15T05:40:28Z} --username autobuild svn://mm:3691/trunk
org.jdom.input.JDOMParseException: Error on line 3: XML document structures must start and end within the same entity.
	at org.jdom.input.SAXBuilder.build(SAXBuilder.java:468)

The CC log does not show the actual error from Subversion. The problem appears to be that SVN issues an error or warning message prior to or in lieu of its XML output. CC, however, seems to parse out partial results and returns a bogus count of modifications. As a result, the build will continue using source code whose exact revision level is undetermined.


SQL Server Day Vector

Here is SQL server code to generate a day vector:

create table day_vector (
  date_index bigint primary key,
  full_date datetime unique,
  year_part int,
  month_part int,
  day_part int

declare @first_date datetime, @last_date datetime
set @first_date = '2000-01-01'
set @last_date = '2050-12-31'

declare @date datetime
set @date = @first_date

while @date <= @last_date begin
  declare @date_index int
  set @date_index = datediff(day, @first_date, @date)
  insert into day_vector
           (date_index,  full_date, year_part,             month_part,             day_part)
    values (@date_index, @date,     datepart(year, @date), datepart(month, @date), datepart(day, @date));
  set @date = dateadd(day, 1, @date)




WinDirStat is a nice utility for inspecting and cleaning up disk space usage.  Similar to TreeSize, but with more visualization features.


Granting EXECUTE to SQL Server User-defined Functions

In SQL Server, you can grant EXECUTE or REFERENCES to a scalar-valued user-defined function.  But if the function is table-valued, then only table permissions can be granted to it, not EXECUTE.

This consideration arose where I was programmatically granting EXECUTE to every user-defined function created by a script.  You can identify whether a function is scalar or table-valued with this query:

select objectproperty(id, N'IsTableFunction') from sysobjects where name=?


Installing WebLogic 8.1 as a Service

When you use the WebLogic 8.1 command installService.cmd, make sure that you first run the corresponding setDomainEnv.cmd first.  If you do not, then the service will be installed without the proper classpath settings (and possibly other settings as well).

Also, there is a command-line argument -execdir:"%USERDOMAIN_HOME%". that is used by the command beasvc within installService.cmdbeasvc seems to do some non-standard processing of the command line.  In particular, if %USERDOMAIN_HOME% ends with a backslash, then the closing quote does not actually close off the string.  It is as if the backslash is escaping the quote.  As a result, the service will be installed with an invalid working directory, one that includes all text on the command line up until the next closing quote.


IEEE 754 Double to Rational Conversion

Here is an algorithm to convert an IEEE 754 double-precision floating point number to a rational (in Java, using the JScience number types):

    private static final Rational doubleToRational(double value) {
        long bits = Double.doubleToLongBits(value);
        int sign = ((bits & 0x8000000000000000L) == 0 ? 1 : -1);
        int fractionBits = 52;
        int bias = 1023;
        int exponent = (int) (((bits & 0x7ff0000000000000L) >> fractionBits) - bias);
        long significand = bits & 0x000fffffffffffffL;
        if (exponent == (bias + 1)) {
            throw new ArithmeticException("cannot convert NaN or infinity to a rational number: "
                    + value);
        if (0 != exponent) {
            significand += 0x0010000000000000L;
        exponent -= fractionBits;
        LargeInteger numerator;
        LargeInteger denominator;
        if (exponent >= 0) {
            numerator = LargeInteger.valueOf(2).pow(exponent).times(sign * significand);
            denominator = LargeInteger.ONE;
        } else {
            numerator = LargeInteger.valueOf(sign * significand);
            denominator = LargeInteger.valueOf(2).pow(-exponent);
        return Rational.valueOf(numerator, denominator);

Java BigDecimal

Here is another reason why Java's BigDecimal is not very useful.  Try this:

BigDecimal.ONE.divide(new BigDecimal("3"))

You'll get this exception:

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

Java sorely needs a rational type.

Blog Archive