... 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 :)

2006-12-19

E4X Documentation

It is hard to find readable documentation on ECMAScript E4X.  Adobe's Flex 2 documentation is much easier to read than the E4X specification.  Look under Programming ActionScript 3.0 / Core ActionScript 3.0 Data Types and Classes / Working with XML.  Of course, you must take care using these documents as ActionScript is (mostly) a superset of ECMAScript.

ApexSQL Clean

While evaluating changes to the PetroAra schema, I took a look at the product ApexSQL Clean.  It performs SQL Server dependency analysis, among other things.  The product is pretty slick.

2006-12-14

OLEDB Connection String and UDL files

".UDL".  That's the extension of OLDEB connection string files that I keep forgetting.  By creating and opening an empty ".UDL" file you are presented with a snazzy GUI for building connection strings. The GUI tools is part of the MDAC distribution. You can access a UDL file from ADO by using a connection string like

File Name=c:\somewhere\my.udl;

2006-12-13

Copy a Java Serializable

I'm tired of repeatedly recreating this code to copy a Java Serializable:

private static <OBJECT_TYPE extends Serializable> OBJECT_TYPE copySerializable(
        OBJECT_TYPE object) {
    try {
        ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
        ObjectOutputStream objectOutput = new ObjectOutputStream(byteOutput);
        objectOutput.writeObject(object);
        ByteArrayInputStream byteInput = new ByteArrayInputStream(byteOutput.toByteArray());
        ObjectInputStream objectInput = new ObjectInputStream(byteInput);
        @SuppressWarnings("unchecked")
        OBJECT_TYPE copy = (OBJECT_TYPE) objectInput.readObject();
        return copy;
    } catch (Exception ex) {
        throw new RuntimeException(String.format("unable to copy the object '%s'", object), ex); //$NON-NLS-1$
    }
}

or its threaded equivalent that uses pipes:

private static <OBJECT_TYPE extends Serializable> OBJECT_TYPE copySerializable2(
        final OBJECT_TYPE object) {
    try {
        final PipedInputStream pipeInput = new PipedInputStream();
        final PipedOutputStream pipeOutput = new PipedOutputStream(pipeInput);
        Thread writerThread = new Thread("copySerializable2") { //$NON-NLS-1$
            @Override
            public void run() {
                try {
                    ObjectOutputStream objectOutput = new ObjectOutputStream(pipeOutput);
                    try {
                        objectOutput.writeObject(object);
                    } finally {
                        objectOutput.close();
                    }
                } catch (IOException ex) {
                    throw new RuntimeException(String.format(
                        "Unable to serialize the object '%s'", object), ex); //$NON-NLS-1$
                }
            }
        };
        writerThread.start();
        try {
            ObjectInputStream objectInput = new ObjectInputStream(pipeInput);
            try {
                @SuppressWarnings("unchecked")
                OBJECT_TYPE copy = (OBJECT_TYPE) objectInput.readObject();
                return copy;
            } finally {
                objectInput.close();
            }
        } finally {
            writerThread.join();
        }
    } catch (Exception ex) {
        throw new RuntimeException(String.format("Unable to read the object '%s'", object), ex); //$NON-NLS-1$
    }
}

Java Pipes

I'm also tired of writing the boilerplate in Java necessary to use a pipe.  Here is a helper class, preceded by something that uses it:

private static <OBJECT_TYPE extends Serializable> OBJECT_TYPE copySerializable3(
        final OBJECT_TYPE object) {
    PipeHelper<OBJECT_TYPE> pipeHelper = new PipeHelper<OBJECT_TYPE>() {

        @Override
        protected void write(PipedOutputStream pipeOutput) throws Exception {
            ObjectOutputStream objectOutput = new ObjectOutputStream(pipeOutput);
            objectOutput.writeObject(object);
            objectOutput.close();
        }

        @Override
        protected OBJECT_TYPE read(PipedInputStream pipeInput) throws Exception {
            ObjectInputStream objectInput = new ObjectInputStream(pipeInput);
            @SuppressWarnings("unchecked")
            OBJECT_TYPE copy = (OBJECT_TYPE) objectInput.readObject();
            objectInput.close();
            return copy;
        }
    };
    
    try {
        return pipeHelper.run();
    } catch (Exception ex) {
        throw new RuntimeException(String.format("Unable to copy the object '%s'", object), ex); //$NON-NLS-1$
    }
}



abstract class PipeHelper<RESULT_TYPE> {

    public RESULT_TYPE run() throws Exception {
        final Exception[] writerException = { null };
        final PipedInputStream pipeInput = new PipedInputStream();
        try {
            final PipedOutputStream pipeOutput = new PipedOutputStream(pipeInput);
            try {
                Thread writerThread = new Thread(this.getClass().getName()) {
                    @Override
                    public void run() {
                        try {
                            write(pipeOutput);
                        } catch (Exception ex) {
                            writerException[0] = ex;
                        }
                    }
                };
                writerThread.start();
                try {
                    RESULT_TYPE result = read(pipeInput);
                    if (null != writerException[0]) {
                        throw writerException[0];
                    }
                    return result;
                } finally {
                    writerThread.join();
                }
            } finally {
                pipeOutput.close();
            }
        } finally {
            pipeInput.close();
        }
    }

    protected abstract RESULT_TYPE read(PipedInputStream pipeInput) throws Exception;

    protected abstract void write(PipedOutputStream pipeOutput) throws Exception;
}

2006-12-12

Subversive / SVNKit

I tried installing Subversive, an Eclipse plug-in for Subversion.  I have been watching this plug-in for a while after abandoning Subclipse.  This time I tried Subversive 1.1.0, using version 1.1.0 of the SVNKit client.  The plug-in seemed reasonably stable, but the Eclipse IDE performed abysmally.  A coworker said that he found similar bad performance, but was able to work around it by disconnecting each project from SVN after performing SVN operations.  Another coworker did not see this behaviour.  I uninstalled Subversive, and Eclipse responsiveness was restored.  Perhaps Subversive was doing some sort of tree crawl in the background that eventually finishes, restoring proper responsiveness?  I'll have to re-install some day to find out.

2006-11-23

F3 and Processing

F3 is a new scripting language with an emphasis on UI implementation.  The interactive tutorial really showcases its power.  The key innovation seems to be the binding feature which simplifies interactive graphical programming by reducing the boilerplate code needed to handle events, perform redraws, etc.

In a similar vein, there is a language called Processing.  Processing seems to look more appealing for sandbox work or for my kids to play around with code and graphics.

2006-11-21

WMI Scripting

wmi.hta illustrates how to query the Windows Management Instrumentation from JScript.

2006-11-16

ADO CommandTimeout

The docs say this, but I didn't guess from the API that the CommandTimeout property on a Connection does not actually apply to commands.  It only applies to opening the connection.  To set the timeout for commands, use the CommandTimeout on the Command object itself (i.e. commands do not inherit connections' timeout settings).

2006-11-14

ISO Recorder

ISO Recorder is a small add-on for Windows XP that allows ISO images to be burnt to CD or to rip CDs as ISO images.  It is a smaller installation than Daemon Tools.  It adds context menu items to Windows Explorer for .iso files and for CD devices.

2006-11-09

EJB 3.0 Stand-alone clients

EJB 3.0 has simplified the usage of session beans considerably (and presumably message beans as well).  Gone are home interfaces and PortableRemoteObject.narrow().  The stubs and proxies are all but invisible.  But, clients still need to bootstrap using vendor-specific means.  The "Java EE application client" approach is still suggested (i.e. running your application in a client-side container).  Running outside of a client container (as a "stand-alone" client) still requires vendor-specific JARs and JNDI configuration.  You'd think they fix this.  Someday, perhaps.  Entity beans are gone completely, however -- hooray!  You have to learn the new JPA API, though...

Sysinternals absorbed by the Borg

Sysinternals is now part of Microsoft.

2006-11-02

Subtleties of Java Static Imports

I had a Java class that has a static import for org.junit.Assert.assertEquals which imports a number of signatures including one with arguments String, double, double, double.  I also defined in that class a static method named assertEquals with the argument signature String, double[], double[], double that invoked the JUnit assertEquals.  Under Eclipse 3.2.0, the compiler accepted this code and it worked the intuitive way.  Under Eclipse 3.2.1, the compiler misidentified my call to the double[] version of assertEquals as if I were trying to call the double version, and issued an error message complaining about the type mismatch.

I wondered which behaviour was correct, the 3.2.0 or 3.2.1 version.  I checked the Java Language Specification and it is silent on the subject.  Reading between the lines, however, it would seem that neither the 3.2.0 nor the 3.2.1 behaviour is correct (although 3.2.1 is almost right).  The spec does say that if you statically import a type and also define a type with the same name in the class, a compiler error is issued.  If I extrapolate that rule to include imported members, then the 3.2.1 behaviour is correct, although I would argue that the error message that it gives is misleading or even wrong.  It should give an error message along the lines of "the statically imported method name 'x' conflicts with the definition of 'x' in the class".

2006-10-30

MSDE Installer vs. Disk Space mod 4GB

If you try to use the MSDE installer (e.g. MSDE2000A) on a hard drive that has a multiple of 4GB free, the installer will complain that there is not enough disk space.  Microsoft's workaround is to create a temporary file that changes the amount of free space to something else.

KB301913: BUG: Error Message: "There is not enough space on drive" Occurs When You Extract SQL Server 2000 Downloads

KB811480: BUG: You Receive Error Message: "There Is Not Enough Space on Drive" When You Extract SQL Server 2000 Service Pack 1

2006-10-29

Windows CPU Speed Stepping

Applications that attempt to adjust their behaviour based upon the measured CPU speed (e.g. video games like Unreal Tournament) may behave erratically on lap-tops that use CPU speed stepping to save battery power.  You can turn off speed stepping under XP by going to the Power control panel and selecting the Home Office/Desk power configuration.  I'm not sure how people figured this out -- the control panel does not offer any clues as to what system parameters are adjusted for each setting and the Microsoft documentation is no help either.  It works, though.

2006-10-27

Exchange 2003 vs. Hotmail and others

We had problems today with our Exchange 2003 Server in that a large number of messages were not being delivered.  Looking in the Exchange queues, the messages were variously reported as having statuses like 'The connection was dropped by the remote host'.  I turned on detailed logging, and noticed that all the troublesome messages were using the BDAT SMTP verb instead of the DATA verb.  This was further confirmed by reviewing packet captures using Ethereal.

I have not been able to determine why this is occurring, and whether this has always been happening or just started happening recently.  However, I tried a quick work-around (found on the Net).  I turned off the extended verbs in the SMTP connector (under Routing Groups) by checking the Send HELO instead of EHLO option on the advanced tab.

One possible theory gleaned from Usenet revolves around the Symantec Anti-Virus software that was installed on the Exchange server.  A technical note from Symantec expressly warns against installing the Internet E-Mail Auto-Protect feature on an SMTP server of any kind.  Sure enough, our server had the auto-protect feature installed, and active.  I de-activated it for good measure, but perhaps I ought to uninstall it completely (a major operation on a production email server).  I'll watch it and see if de-activating it is enough.

Another Usenet message referred to scenarios exactly like what I was seeing.  They suddenly started getting timeout errors and such where none had appeared before.  Apparently, they talked about the problem to their ISP and the ISP made unspecified changes that fixed the problem.  I don't know whether to take these messages seriously or whether they were just using the ISP story as a convenient way to wrap up a long interactive discussion after finding a simple mistake was causing the problem.

Incidentally, using the Microsoft IIS logging format was more useful than the W3C Extended option because the former could be more readily loaded into Excel.  Furthermore, it took me a while to figure out how to get the extra fields (i.e. useful fields) configured in the latter by configuring the properties after selecting the logging type.  The IIS format automatically includes all of the extra fields.  Just don't keep a log file open in Excel for an extended period -- it seems to block all logging and possibly even the queue servicing.

SMTPDIAG

Microsoft has a nice tool for diagnosing SMTP delivery problems through Exchange, SMTPDIAG.  It didn't help me with the problem described above, however, since it uses the DATA verb instead of the BDAT verb.

2006-10-26

Javascript 1.7

Javascript 1.7 introduces a number of new features, including let.  I couldn't figure out what the difference was between for(var i ...) and for(let i ...) - until I tried it.  It hadn't occurred to me before, but Javascript does not (that is, did not) have block scope.  It only has global and function scopes.  So the first example introduces a new variable i within the enclosing function (or, failing that, global) scope.  The let version introduces i within block scope.

Here is a little sandbox for playing with Javascript 1.7 (I'd only expect it to work in Mozilla, of course).

2006-10-25

Exchange

When an ActiveDirectory user account has been disabled, it might render the user's mailbox in Exchange inoperative.  Outlook will issue a vague object about being unable to access the folders.  The event log on the Exchange server will record report a "log on" failure for the mailbox with the error code -2147221231.  There is a fix.  In ActiveDirectory, edit the user's properties under Exchange Advanced\Mailbox Rights.  Make sure that at least one user has the 'Associated External Account' permission.  If no user has that permission, assign it to the SELF account.

This issue is discussed by the Microsoft knowledge base entry KB278966.

2006-10-24

Outlook vs Exchange vs Email aliases

Using Exchange 2003, I was struggling to set up an aliasing scheme so that I could have a 'network administration' group which would serve as a target for incoming email relating to network issues such as ICANN registration, ISP correspondence, etc.  The set of internal users responsible for this correspondence could then vary over time by being added as members of the group.  Also, I would grant the 'on behalf of' right to those users so that they could send outgoing email from that address.

Unfortunately, it was a struggle.  Here are the problems:

  1. Changes made to the Exchange server do not propagate in real time.  For example, when I added a new user or mailbox, they did not appear in the Global Address List.  I had to manually rebuild the 'Offline Address List' on the Exchange server to make them appear.  By default, this happens infrequently.  Interestingly, when you trigger the rebuilding process, Exchange warns that the process could take several hours.  With 50-ish mailboxes, it took a few minutes.
  2. When you try to send email on behalf of someone else, you cannot simply type their email address into the 'From' box -- even if Outlook recognizes and completes the address for you.  You must select the address manually from the Global Address List.  If you don't do it this way, the email will be bounced back with the misleading error message: 'You do not have permission to send to this recipient' (read: you do not have permission to send as this sender).
  3. You cannot send mail on behalf of an email address associated with a group.  Exchange does not support that operation.

Incidentally, you do not seem to have to add a person to the 'On Behalf Of' list for a mailbox when that person has administrative rights.

2006-10-19

Mathematica RealTime3D

I keep forgetting this recipe, so I'm writing it down... You can activate Mathematica's interactive 3D renderer by entering the command:

<<RealTime3D`

You can restore the normal mode of operation thus:

<<Default3D`

2006-10-18

NoScript and Other Firefox Extensions

I installed a handy new Firefox extension, NoScript, that blocks all Javascript except for a white list of sites.  While I'm at it, here are the other extensions that I routinely install:

  • DOM Inspector
  • Web Developer
  • IE View
  • Javascript Debugger

2006-10-17

Dicodess

I tried to evaluate Dicodess, a distributed co-operative decision support system.  I couldn't get it to run.  I was following the 'robots' tutorial.  After pressing 'continue' on the 'Project Properties' page, the application simply exits.  No error messages are issued to the console, and there do not seem to be any log files.  At first I thought that the JVM that I was using, 1.5.0_07, was too new, but the system fails the same way under 1.4.2_12.  After failing once, the system hangs on start-up at the stage 'Initializing Working Memory'.  The only way to recover from this state is to delete the contents of the Dicodess 'projects' directory.

2006-10-13

Decoding MS Product Keys

Here is some JScript that can be used to display the product keys used to register various Microsoft products on the current machine.

2006-10-12

JIRA Crash

JIRA crashed today, complaining that the segments file in the indexes\issues directory of the repository was missing.  I tried to rebuild the indexes, but then it complained that it couldn't delete the index files.  The solution was to restart JIRA and then rebuild the indexes.

Perhaps another process was locking the JIRA files -- a backup or virus scan?

SWT Widget.dispose() Doesn't Get Called

The API documentation for org.eclipse.swt.widgets.Widget#dispose() has this interesting tidbit:

NOTE: This method is not called recursively on the descendents of the receiver. This means that, widget implementers can not detect when a widget is being disposed of by re-implementing this method, but should instead listen for the Dispose event.

Thus, the only reliable way for a widget to know if it has been disposed is to add a DisposeListener to itself.

3D References in Excel

You can create 3D references in Excel using cell addresses like Sheet1:Sheet4!A1:B10.  If you are creating a range using the mouse, you can extend it in the third dimension by shift-clicking on the tab of another sheet.

Worksheet-Scoped Names in Excel

It is possible to created names in Excel that are scoped to a worksheet, but there are gotchas to watch out for.  If you prefix a name with its worksheet name, e.g. Sheet1!MyName, then the name will be local to that worksheet.  That seems easy enough, but if you forget the prefix then you get a global name.  Subtleties can arise when you copy a worksheet because Excel will create local copies of all names in the new worksheet -- even copies of the global names.  Note that local names can shadow global names, although Excel will not let you create such a situation in the sheet that is the target of a global name.

If you want the references to be relative to the current sheet, and not the sheet that was active when the name was defined, you must prefix the cell reference with an exclamation mark (i.e. !B1 will work but B1 will reference the original sheet).

2006-10-11

Unofficial HTML Canvas Tag

There is a new "HTML5" element used for drawing:  Canvas.  It originally was implemented by Apple in Safari, but Firefox 1.5 supports it as well.  The tag is documented at Mozilla and at WhatWG.

MochiKit, PlotKit

MochiKit is a Javascript library.  PlotKit is a graphing library that builds upon it.

2006-10-10

Javascript Split Function

I discovered a discrepency in the way that the Microsoft and Mozilla implementations of Javascript handle the 'split' function.  Consider this expression:

"!abc!def!ghi!".split(/!/)

Mozilla returns an array with five elements, the first and last elements being empty strings.  Microsoft returns only three elements, having dropped the first and last elements.  Intuitively, Mozilla seems correct.  The definition of split in the ECMA-262 standard is difficult to read, but appears to support Microsoft's interpretation.

WSH/HTA Droplet

Here is a template for a Windows script droplet that forwards its arguments to an HTA.

2006-10-03

Finding Extreme Values in XSLT

Here's a neat trick to find the maximum value for an element using XSLT:

<xsl:variable name="max-date">
  <xsl:for-each select="/jira-work-activity/entry/date">
    <xsl:sort order="descending"/>
    <xsl:if test="position()=1"><xsl:value-of select="."/></xsl:if>
  </xsl:for-each>
</xsl:variable>

2006-10-02

Eclipse RCP Editors

I kept getting the following exception when trying to open an editor part using Eclipse RCP:

PartInitException: Unable to open editor, unknown editor ID: my.editor.id

The message was a lie -- I had registered an editor under the stipulated ID.  But when I debugged into Eclipse code, I could see that my editor had not been registered.  Investigating further, I found the following message in the application log:

!MESSAGE Plugin my.plugin, extension org.eclipse.ui.editors
Required attribute 'icon' not defined

It appears that the 'icon' attribute is required, even though it is not shown as such in the plug-in manifest editor.  Note that the condition is reported as a 'message' and not an 'error', so if you don't go looking into the application log, you won't see it.

2006-09-27

Javascript Clock

Here is a simple clock in HTML/Javascript:

<p>The time is <span id="clock">unknown<script language="javascript">
function clockTimeout()
{
    var clockSpan = document.getElementById("clock");
    var timeNode = document.createTextNode(new Date().toTimeString().substring(0, 8));
    clockSpan.replaceChild(timeNode, clockSpan.firstChild);
    window.setTimeout('clockTimeout()', 1000);
}
clockTimeout();
</script></span>.</p>

2006-09-11

Hierarchies in SQL

I created an SQL script that demonstrates the 'interval' approach to managing hierarchies in SQL.  It is based upon approaches presented in Trees in SQL and Nested Intervals with Farey Fractions

2006-09-09

Accounting Site

I was reading a good site that has introductory accounting material, accountingcoach.com.

Concept Maps with VUE

VUE is an interesting tool for creating concept maps.  There is an associated project on SourceForge.

2006-09-07

SWT Tools

Two useful SWT tools, Sleak and SWT Spy can be found on the SWT Tools page.

Java Testing Tools

I've been trying to remember the names of  some Java testing tools that I came across a couple of years ago.  Well, I stumbled upon them again reading someone's blog.  Cobertura is an open-source test coverage tool.  Jester is a tool that attempts to verify that your tests are meaningful by applying code changes to both test and under-test code.

Eclipse User-defined Code Folding

User-defined code folding has been a long-standing request for Eclipse, but has been deferred repeatedly and is still not in Eclipse 3.2.  There is, however, a 3rd party plug-in that provides it:  Coffee-Bytes Platform Support.

2006-08-30

ALDSP Null Pointer Exceptions

I have seen ALDSP null pointer exceptions a few times, with stack traces like this:

Caused by: java.lang.NullPointerException
        at com.bea.ld.dsmediator.update.DataServiceMediator.populateBindingTree(DataServiceMediator.java:2183)
        at com.bea.ld.dsmediator.update.DataServiceMediator.populateBindingTree(DataServiceMediator.java:2230)
        at com.bea.ld.dsmediator.update.DataServiceMediator.populateBindingTree(DataServiceMediator.java:2230)
        at com.bea.ld.dsmediator.update.DataServiceMediator.parseDataGraph(DataServiceMediator.java:1990)
        at com.bea.ld.dsmediator.update.DataServiceMediator.getUpdatePlan(DataServiceMediator.java:593)
        at com.bea.ld.dsmediator.update.DataServiceMediator.submit(DataServiceMediator.java:509)

Today it arose when I tried to submit an update to a DTO that showed a parent-child hierarchy.  I didn't seriously think that the update would work, but I don't think that an NPE is a particularly helpful error message.  I looked at the source of DataServiceMediator#populateBindingTree, but it was hard to identify the errant line.

2006-08-28

ALDSP Update Order

In ALDSP 2.0, the manual states that when updating, containers are processed prior to contained objects, except when deleting when the reverse is true (see the Update Order section of the Client Application Developer's Guide).  It is interesting that the 2.1 version of the same manual makes no such claim.  Indeed, there is a reference in the 2.1 release notes to a bug (CR237186) in which update order is not respected.  It states that updates occur in alphabetical order, although it is not clear whether it is alphabetical by table name, data service name, or element name (the release notes weakly suggest that it might be element name).

Experimentation with 2.1 reveals that update order for insertions appears to be correct (container first) regardless of alphabetical order.  Deletions, on the other hand, do not appear to work properly.  I tried naming the elements in the DTO so that the container was alphabetically before the child, and vice versa.  Neither worked.

The 2.1 client guide suggests that an override function should be used to control update order.  I was unable to get even a trivial override function to work -- I would always get a NullPointerException.  Once I got even a single NPE, blanking out the override function in data service's property page would not restore functionality.  I would have to hand-edit the pragma to remove the override function XML element completely.

Incidentally, I couldn't get override functions to compile without adjusting the server classpath for the application to include wlsdo.jar from the liquidata/lib directory.  The manual does not mention this..

ALDSP Cascaded Deletes

Using ALDSP, there are problems if you try to delete an object that owns its children (and both are mapped into the same document).  Even though ALDSP inspects the foreign key constraints, it does not use this information to figure out cascaded deletes.  If you simply delete the parent object, you will get an exception like:

com.bea.ld.dsmediator.DataServiceException:
  java.sql.SQLException: [BEA][SQLServer JDBC Driver][SQLServer]
    DELETE statement conflicted with COLUMN REFERENCE constraint 'FK_ITEM_FACT'.
    The conflict occurred in database 'mmsandbox', table 'FACT', column 'ITEM_ID'.

To perform a cascaded delete successfully, you must first delete all of the child nodes from the data graph, then the parent node.  When you submit the altered data graph, it will do the right thing (in the right order, apparently, not in alphabetical order as claimed in the 2.1 release notes).

ALDSP vs. Multi-table Updates Again

After working throw the "Invalid SQL" problem, I returned to plan to try a parent-child insertion having renamed the child table so that it was alphabetically after the parent table.  No luck.  I also tried mapping the parent key field to the DTO in both the parent and child levels, hoping that that would make the shared nature of the key more apparent to the updater.  It didn't work.

The exception is:

java.rmi.RemoteException: EJB Exception: ; nested exception is: 
  com.bea.ld.dsmediator.DataServiceException:  Primary key attribute ITEM_ID on Object FACT is not provided.

ALDSP Invalid SQL Specified

I tracked down the cause of the ALDSP exception mentioned in yesterday's entry.  The stacktrace is exhibited below.  It is caused by specifying setting the 'auto number' property of a data service key to 'sequence' for anything other than Oracle or DB2.  In my case, I was using MS SQL Server but had accidentally selected 'sequence' instead of 'identity'.  Looking at the code for JDBCAdaptor.populateSequence, I saw that it calls SQLGenerator.getSQLSequenceFetch to generate an SQL statement to get the next sequence value.  The latter returns null for any database type other than Oracle or DB2.  The caller then tries to execute 'null' as the SQL statement which the JDBC driver catches as an error.  I suppose that one of the routines involved should have caught the mistake and thrown a more informative error message.

Here is the stacktrace:

[SQLServer JDBC Driver]Invalid SQL specified.
com.bea.ld.dsmediator.DataServiceException: java.sql.SQLException: [BEA][SQLServer JDBC Driver]Invalid SQL specified.
        at com.bea.ld.dsmediator.update.JDBCAdaptor.save(JDBCAdaptor.java:248)
        at com.bea.ld.dsmediator.update.DataServiceMediator.submit(DataServiceMediator.java:500)
        at com.bea.ld.dsmediator.update.DataServiceMediator.nestedSubmit(DataServiceMediator.java:1871)
        at com.bea.ld.dsmediator.update.DataServiceMediator.executeUpdatePlan(DataServiceMediator.java:1828)
        at com.bea.ld.dsmediator.update.DataServiceMediator.submit(DataServiceMediator.java:511)
        at com.bea.ld.dsmediator.update.DataServiceMediator.submit(DataServiceMediator.java:227)
        at com.bea.ld.ServerBean.submit(ServerBean.java:529)
        at com.bea.ld.Server_ydm4ie_EOImpl.submit(Server_ydm4ie_EOImpl.java:856)
        at com.bea.ld.Server_ydm4ie_EOImpl_WLSkel.invoke(Unknown Source)
        at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:492)
        at weblogic.rmi.cluster.ReplicaAwareServerRef.invoke(ReplicaAwareServerRef.java:108)
        at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:435)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
        at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:147)
        at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:430)
        at weblogic.rmi.internal.BasicExecuteRequest.execute(BasicExecuteRequest.java:35)
        at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224)
        at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
Caused by: java.sql.SQLException: [BEA][SQLServer JDBC Driver]Invalid SQL specified.
        at weblogic.jdbc.base.BaseExceptions.createException(Unknown Source)
        at weblogic.jdbc.base.BaseExceptions.getException(Unknown Source)
        at weblogic.jdbc.base.BaseStatement.commonValidateSQL(Unknown Source)
        at weblogic.jdbc.base.BaseStatement.execute(Unknown Source)
        at weblogic.jdbcx.base.BaseStatementWrapper.execute(Unknown Source)
        at weblogic.jdbc.wrapper.Statement.execute(Statement.java:386)
        at com.bea.ld.dsmediator.update.JDBCAdaptor.populateSequence(JDBCAdaptor.java:328)
        at com.bea.ld.dsmediator.update.JDBCAdaptor.save(JDBCAdaptor.java:113)
        ... 17 more

ALDSP Primary Key Not Provided

I got to the bottom of the exception "Primary key attribute ... on Object ... not provided".  It is caused when you insert boilerplate XML container elements in your DTO.  For example, if the document looks like this:

<Item id="1" type="1">
  <PropertyList>
    <Property id="1" value="2"/>
    ...

and the Item element is mapped to the parent table and the Property element is mapped to the child table, then you will get the exception.  However, if you delete the organizing element PropertyList:

<Item id="1" type="1">
  <Property id="1" value="2"/>
  ...

then the mapping works properly and updates will work.

ALDSP Recursive Type Definitions

I had a schema that defined a HierarchyList as a list of Hierarchy elements each containing a list of Item elements each containing (recursively) a list of Item elements.  When I tried to submit an update that added an empty Hierarchy element to an empty HierarchyList, I got a StackOverflowException (with no stack trace).  I guess ALDSP does not handle recursive schemas gracefully.

2006-08-25

ALDSP vs. Multi-table Updates

I created a data service that reports on a couple of tables that have a parent-child relationship.  This was SQL Server, so the primary keys were auto-generating 'identity' keys.  If I updated the ALDSP document to create a new parent node and submit it, all is well.  But if I submit a document that creates both a parent and child node, then the update fails complaining that no value was supplied for the parent key in the child table.  "Aha!" I thought, I remember reading in the BEA documentation that updates occur in alphabetical order by table name and, as luck would have it, that was the wrong order for my tables.  So I renamed the child table to sort alphabetically after the parent table and tried again.

No success (yet).  I keep getting the exception::

java.sql.SQLException: [BEA][SQLServer JDBC Driver]Invalid SQL specified

I have turned all of the logging in ALDSP, WebLogic, and the relevant application to full-on maximum -- but ALDSP doesn't show the SQL in question.  In fact, I get this error even when I try to update the parent alone, so something else is broken.  I'll keep looking...

MS SQL Server Enterprise Manager vs. BEA WebLogic Workshop

I find that if I have the MS SQL Server Enterprise Manager open at the same time as BEA WebLogic Workshop, the latter feels much more clunky to use.  Frequently, there are long delays between the moment I type a key or click the mouse, and when the character appears or the click is processed.  As soon as I close Enterprise Manager, the behaviour goes back to normal.  I wonder if there is some adverse interaction, or if Enterprise Manager is interfering with everything else, Workshop or otherwise?  I might just be noticing it in Workshop since it is not exactly snappy at the best of times.

ALDSP vs. Renaming Tables

I renamed a table in an SQL table and then used Workshop's 'update metadata' function to try to synchronize an ALDSP project that used the renamed table.  So now I had two physical data services for the renamed table, one for the old name and one for the new name.  The new data service had none of the relationships, presumably because ALDSP was not smart enough to find the foreign keys that involve the existing tables (fair enough).  So, I tried some hand surgery to copy the relationships from the old data service into the new.  Bad idea.  ALDSP kept trying to second guess me and started modifying (and even commenting out!) data service functions all over the place.  It got so tangled up that my only recourse was to blow away all the physical data services and rebuild them from scratch.  Ouch.  Moral of the story -- when you rename a table, hand edit the corresponding physical data service to match.

Storing Original Units of Measure

I have been trying to track down the source of the legend that there exist jurisdictions in which regulations or laws demand that the original units of measure be stored in databases.  So far, all I have found is a passing reference to this fact in section 8.2 (units of measure, paragraph 8.2.3) of the PPDM Architectural Principles guide, version 3.7.

Submitting AquaLogic Documents

I discovered that when you build an ALDSP document that contains two related entities, you must take care when you map the join fields to the document.  You must map the primary key side of the relationship to the output document.  If you map the foreign key side, then you will get a runtime error message like:

com.bea.ld.dsmediator.DataServiceException: Primary key attribute PROPERTY_ID on Object FACT is not provided.

Actually, the rule may be that you have to map the key from the outer element (regardless of which side of the foreign key constraint it comes from).  More experimentation is needed.

2006-08-24

Data Models

While noodling about how to create a credible metamodel for a particular model, I started considering whether a dimensional model might be a better choice than an entity-relationship model.  I thought that I would take this opportunity to capture links to relevant foundational papers:

2006-08-22

Python IDEs

PyScripter is a nice, free, IDE for Python.  PyDev seems to be a commonly used Eclipse plug-in, but it is switching to a commercial model with all the good features in the commercial PyDev Extensions product.

2006-08-17

Ant, WebLogic 8.x, JDBC Connection Pools

WebLogic provides an Ant task called wlconfig that can be used to change lots of settings in the WLS configuration.  For example, you can create a JDBC connection pool and data source like this:

    <wlconfig url="t3://localhost:7001" username="weblogic" password="weblogic">

      <query domain="mydomain81" type="Server" name="myserver81" property="server-jmx-name"/>

      <query type="JDBCConnectionPool" name="ZotPool">
        <delete/>  <!-- does nothing if the pool does not exist -->
      </query>
      <create type="JDBCConnectionPool" name="ZotPool">
        <set attribute="DriverName" value="weblogic.jdbcx.oracle.OracleDataSource"/>
        <set attribute="URL" value="jdbc:bea:oracle://mm1:1521"/>
        <set attribute="Properties" value="serverName=mm1;SID=dev1;portNumber=1521;user=myuserid"/>
        <set attribute="Password" value="mypassword"/>
        <set attribute="ShrinkingEnabled" value="true"/>
        <set attribute="InitialCapacity" value="0"/>
        <set attribute="TestConnectionsOnReserve" value="true"/>
        <set attribute="TestTableName" value="SQL SELECT 1 FROM DUAL"/>
        <set attribute="Targets" value="${server-jmx-name}"/> <!-- must be the last attribute -->
      </create>

      <query type="JDBCTxDataSource" name="ZotDataSource">
        <delete/>  <!-- does nothing if the data source does not exist -->
      </query>
      <create type="JDBCTxDataSource" name="ZotDataSource">
        <set attribute="JNDIName" value="ZotDataSource"/>
        <set attribute="PoolName" value="ZotPool"/>
        <set attribute="Targets" value="${server-jmx-name}"/>
      </create>

    </weblogic8x.wlconfig>

Changing ALDSP End Points

I was trying to find a way to change ALDSP end points programmatically -- without having to go into the ALDSP console and manually retarget the physical stores.  I was hoping for a way to do this similar to the work I was doing with WebLogic JDBC pools and JMX.  Alas, there is no equivalent.  BEA did point out, however, the information is stored the XML configuration file:

admindomain/liquiddata/myaldspappLDConfig.xml

The file is read when the application is deployed.  So it is at least possible to make these changes, though it involves some XML hackery.

JMX Consoles: MC4J, EJAM, jManage

I used MC4J, a standalone JMX console that can access various server types -- including WebLogic which was my interest.  I also found, but did not try:

  • an Eclipse plug-in called EJAM
  • a web and command-line based tool called jManage

2006-08-14

JUnit 4.0 BeforeClass Annotation

The JUnit @BeforeClass annotation has different semantics than the BeforeClass property in TestNG.  JUnit's version is invoked before any instances of the test case class are instantiated and, thus, can only access static features of the class.

Another gotcha to watch out for is that JUnit does not invoke any of the @BeforeClass or @Before methods of the superclasses of the test class.

I note that the Eclipse wizard for creating JUnit test cases does not permit you to specify a superclass -- is this a hint that the practice is discouraged?  Delegation appears to be the alternative, along with the use of static fields (ugh -- global variables).

2006-08-08

Clay

I found a comfortable little Eclipse plug-in for editing SQL schemas:  Clay.

2006-08-01

HTAs

I made a simple "hello world" HTA.

2006-07-31

WebLogic 8.1 vs Admin Password

In WebLogic 8.1, if you change the administrator's password from the console, the server will fail to start when you next restart it.  The error message is:

<BEA-090402> <Authentication denied: Boot identity not valid; The user name and/or password from the boot identity file (boot.properties) is not valid. The boot identity may have been changed since the boot identity file was created. Please edit and update the boot identity file with the proper values of username and password. The first time the updated boot identity file is used to start the server, these new values are encrypted.>

The solution proposed in the error message works.

2006-07-14

Visio: Office vs Visual Studio

Files written using Visio 2003 (from Office 2003) cannot be read from the Enterprise Architect version of Visio that comes with Visual Studio 2003.  The latter appears to be compatible with Visio 2002, so if you save files in that format, all is well.

2006-07-13

Crude Code Line Counting

I used the following UNIX pipe to perform crude code line counting:

find . -name '*.java' -not -wholename '*/generated/*' -exec cat {} \; |
sed -e '/^[ \t]*$/d' |
wc -l

Every non-blank line is counted.

2006-07-12

BCEL and ASM

The BCEL project (for Java bytecode manipulation) seems to be inactive.  The site suggests looking at ObjectWeb's ASM project.  ASM has nice Eclipse plug-in.

2006-07-07

Facelets and JBoss Seam

Facelets is an interesting technology that makes JSF a little easier to use.  It seems to be a plug-in replacement for JSP that adds some Tapestry-like features.  I ran across Facelets while reading about JBoss Seam, yet another application framework in the Web space.

2006-07-04

TOra

There appears to be an open source sibling to TOAD called TOra.  [Postscript, 2006-07-14:  There are bugs in TOra that are so obvious that I can't help thinking that the TOAD guys have purposely introduced them to drive business their way.  TOra is still useful, though.]

XML Namespace Oddities in ALDSP

I was confused about the behaviour of namespaces in BEA ALDSP.  It appeared to be ignoring namespaces for all but the root elements of data service types.  Well, it was ignoring them.  This is because when you create an XML Schema in Workshop, it does not specify the elementFormDefault.  I keep forgetting that elementFormDefault only applies to local elements, not global ones, and that the default behaviour is unqualified, in defiance of common usage.  The moral of the story is to manually add elementFormDefault="qualified" to the XSD.

Oracle Agent Won't Start

Our Oracle installation mysteriously stopped working.  In particular, the Oracle Agent service would not start (OracleOraHome92Agent).  The Windows Event Viewer was no help, it simply said "Agent service failed to launch the agent process." and "Faulting application agntsrvc.exe, version 0.0.0.0, faulting module unknown, version 0.0.0.0, fault address 0x00000000.".  When I manually started the service from the services control panel, I got the additional helpful message "The handle is invalid".

I searched the Web for advice, but none of the suggestions were helpful.  For example, one site suggested turning on tracing by adding the directive "dbsnmp.trace_level=admin" or "agentctl.trace_level=admin" to the file "${ORA_HOME}/network/admin/snmp_rw.ora", but those settings were not being respected.  In fact, there was no evidence whatsoever in the Oracle directory that any processes were being started -- nothing in the log directory and nothing in the trace directory.

I used the SysInternals FILEMON utility to see what files were being accessed.  It turns out that the service was attempting to launch a program from the C: drive even though Oracle was installed on the C: drive.  This, in turn, was due to the fact that the Oracle registry entries had been overwritten with invalid values (due to an inappropriate .REG file being loaded).

All was well after I corrected the erroneous registry entries, pointing Oracle back to its true home directory.

2006-06-30

Tomcat Deployment By Reference

You can deploy web applications and static content in Tomcat without dropping files into the webapps directory.  This is useful if you want the content to reside outside of the Tomcat directory tree.  You do this by putting a Context fragment in the host's configuration directory (e.g. ${TOMCAT_HOME}/conf/Catalina/localhost).  That is, use an XML file that looks like this:

<Context path="/mycontent" docBase="c:\somewhere\mycontent"/>

The docBase can be a WAR file.

2006-06-28

The QName Saga Continues

Sun "fixed" the QName bug as of JDK 1.5.0_07.  That is, they changed the serialver of QName back to what it used to be back in JDK 1.4.  However, this "fix" is problematic since many vendors have already issued patches to accommodate the bug.  For example, BEA has an elaborate workaround to make WebLogic 9.1 interoperate with older version of QName (e.g. as you might find in ALDSP 2.1/WebLogic 8.x).  That workaround is now broken with JDK 1.5.0_07.

However, Sun has thoughtfully provided the system property:

-Dcom.sun.xml.namespace.QName.useCompatibleSerialVersionUID=1.0

Sparse documentation about this magic incantation can be found in the JAXP 1.3.1 release notes.  When this property is defined, QName will use the serialver ID that existed for only a few microrevs of JDK 1.5.  For reference, here are the relevant serialvers:

Prior to JDK 1.5: -9120448754896609940L
JDK 1.5.0, microrevs _00 through _06: 4418622981026545151L
JDK 1.5.0_07 (and hopefully, everything greater): -9120448754896609940L (once again)

Interestingly, the JDK 1.5.0_07 release notes say that the relevant bug in the Java Bug Parade is "fixed", but the notes for that bug say that no action was taken (which is not true).

WebLogic 9.x vs. JDK 1.5.0_07

WebLogic 9.x won't start at all under JDK 1.5.0_07, even if ALDSP is not in the picture at all.  There seems to be some component within the server that still wants to use the '4418' version of QName.  The magic incantation above will fix the problem.  Check out the thread "javax.xml.namespace.QName incompatible" in the BEA WebLogic server newsgroup.

2006-06-26

Mysterious Stale Data in JIRA

Okay, it happened again.  This time, a JIRA item (RAPT-558) did not show in the All filter for the RAPT project -- or any other filter for that matters.  You could load the item directly, it just didn't appear in any lists.  Rebuilding the indexes corrected the problem.

Oracle, SQL*Plus, PL/SQL

SQL*Plus will behave as you expect when executing this sequence:

variable result number;
update zot set x=x+1 returning x into :result;
print result;

but not this sequence:

variable result number;
select count(*) into :result from user_catalog;
print result;

In the latter case, the SELECT statement is accepted and executed, but the INTO clause is not respected.  On the other hand, you can make it work by using a PL/SQL block:

variable result number;
begin
  select count(*) into :result from user_catalog;
end;
/
print result;

While we're on the topic of SQL*Plus, here are some useful snippets that I haven't captured before...

set echo on
whenever sqlerror exit failure

define supplied_user = &&1
define supplied_tablespace = &&2

prompt Creating tables for &&supplied_user in &&supplied_tablespace

declare
  table_count number;
begin
  select count(*) into table_count from user_catalog where table_name='ZOT';
  if 0 = table_count then
    execute immediate
      'create table &&supplied_user..zot (x integer) '
      || ' tablespace &&supplied_tablespace'
      ;
  end if;
end;
/

Note the two dots in "create table &&supplied_user..zot".  The second dot is needed because SQL*Plus will gobble the first dot it sees after any use of the "&" operator (unless you change that behaviour using SET CONCAT).

2006-06-23

Windows Service Dependencies

You can add a dependency between one Windows service and another by creating a REG_MULTI_SZ key with the name:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\dependent service name\DependOnService

The value is a newline-delimited list of prerequisite service names (identified by their registry key name).

2006-06-21

<a name="Mysterious_Stale_Data_in_JIRA">Mysterious Stale Data in JIRA</a>

Twice now we have run into problems in JIRA where data shown in an issue list differs from the detail page of an issue.  The first time, the state of an issue was wrong on the issue list.  The second time, the summary was wrong.  The first time, I cleared the issue cache -- even though the cache was supposedly disabled.  This appeared to clear the problem, but someone else had also added a comment to the issue so I don't which action (if either) caused the update.  The second time, I restarted JIRA to no effect.  The problem went away after I changed the summary of the issue, although someone else had tried that a couple of times already.

The next time this occurs, I am going to try re-indexing using Administration/System/Indexing.

2006-06-20

File URLs in Firefox

In Firefox, it is possible to trust file URLs on a configured set of sites.  Add the lines like this to user.js:

user_pref("capability.policy.policynames", "localfilelinks");
user_pref("capability.policy.localfilelinks.sites", "http://site1 http://site2");
user_pref("capability.policy.localfilelinks.checkloaduri.enabled", "allAccess");

For some reason, it is hard to add these preferences using about:config.  You can create these keys, but they are not shown on the configuration page so you are typing blind.  They do appear in the prefs.js file, however.  More information on configurable security policy can be found at:

http://www.mozilla.org/projects/security/components/ConfigPolicy.html

2006-06-16

OpenWiki

To delete a page in OpenWiki, add the line "#DEPRECATED" to the top of the page.  Then, run the administrative page deprecate.asp to actually delete deprecated pages.  You must edit that script first because it is shipped in a non-functional state (for protection).  Also, it includes a parameter for the minimum length of time that a page must remain unedited before it is deleted.

2006-06-12

Eclipse RCP

When you use the export function of an Eclipse RCP production configuration, it overwrites the plugin.xml of the main application project to update the 'about' screen.  This behaviour is a bit unexpected, and is not friendly to the version control system.

2006-06-09

Subversion and Ant

Here is a cheesy, but effective, way to recover the current Subversion revision number of a directory using only Ant -- the Subversion client is not necessary:

<project name="svn-version" default="get-svn-revision">

  <xmlproperty file="../.svn/entries" prefix="svn"/>

  <target name="get-svn-revision">
    <echo message="${svn.wc-entries.entry(revision)}"/>
  </target>

</project>

I call this method cheesy, because it depends on the internal details of the SVN entries file, the format of which is subject to change.  Also, it relies on the fact that the first entry is the one that contains the revision number for the directory since the Ant xmlproperty task does not handle duplicate elements.  The method has its charms, however, since it does not require the Subversion client to be on the path (or even installed), and does not need any temporary files (such as those the xslt task might demand).

QA

A good quality in a QA person is the ability to raise issues with developers without immediately polarizing the discussion.  The personalities of both QA people and developers make this a challenging proposition sometimes.

2006-05-31

Subversive

I've been unhappy with the Subclipse Subversion plug-in for Eclipse.  I'm going to try another plug-in:  Subversive.

2006-05-15

Eclipse vs PERM GEN Space

From time to time, Eclipse throws an OutOfMemoryError, complaining that it is out of PERM GEN space.  A bit of reading reveals that PERM GEN space is used as a garbage collection generation space for permanent objects -- such as pieces of classes that are never unloaded.  You can get this error if you load lots of classes.  To increase the size of the PERM GEN space, use:

-XX:MaxPermSize=128m

The default is 64m.

Tomcat and JConsole

If you are running Tomcat as a service, you will not be able to attach to it using JConsole using the 'local' protocol.  You must configure it to accept remote connections, e.g.

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8081
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false

This recipe does not perform any authentication.  Also, I found out that if you have any -X Java options, they must appear last.  When I tried to put the various -D settings listed above after the -X options, Tomcat (and presumably the JVM) quietly ignored them all.

2006-05-11

ALDSP 2.1 Optimistic Concurrency

When updating, ALDSP generates SQL statements like

UPDATE MY_TABLE SET MY_COLUMN='NEW VALUE' WHERE MY_ID='PRIMARY KEY' AND MY_COLUMN='OLD VALUE'

and inspects the update count to see whether a concurrency error has occurred.  The set of columns that are checked in this way can be either all columns in the SDO object, only the modified columns, or a set of user-specified columns.  However, it turns out that ALDSP will quietly drop columns of data types that are difficult to compare for equality.  At time of writing, this set reasonably includes BLOB, CLOB, LONGVARBINARY, LONGVARCHAR, VARBINARY, and BINARY.  Just as reasonably, but perhaps unintuitively, it also includes FLOAT and DOUBLE.

The list of troublesome data types was gleaned from the methods getUpdateSql() and canBeIncluded() in the class com.bea.ld.dsmediator.update.SQLGenerator.

See also the exchange on this topic in BEA's newsgroups.

2006-05-03

Generic Arrays in Java

Java 1.5 does not support arrays of generic types well (e.g. MyType<Thing>[]).  Avoid them.  See section 7.3 of the Java generics tutorial.

2006-04-12

ALDSP 2.1 vs QName

I tried the same trick that we used for ALDSP 2.0 -- placing a compatible version of javax.namespace.QName in the lib/endorsed directory of the JVM being used by WebLogic 8.1.  That change permitted a standalone Java 1.5 client to execute correctly.  However, running the same code in a servlet hosted by WebLogic 9.1 generated this exception:

<Apr 12, 2006 10:55:21 AM MDT>
<Error>
<HTTP>
<BEA-101017>
<[weblogic.servlet.internal.WebAppServletContext@bc7c0 - name: 'aldsp-servlet.war', context-path: '/aldsp-servlet']
Root cause of ServletException.
com.bea.dsp.dsmediator.client.exception.SDOMediatorException: java.rmi.UnmarshalException: failed to unmarshal interface com.bea.ld.QueryResult; nested exception is:
java.lang.ClassNotFoundException: Failed to load class com.bea.ld.server.QueryResultImpl
at com.bea.dsp.dsmediator.client.XmlDataServiceBase.invokeFunction(XmlDataServiceBase.java:322)
at dstest.mmsandbox.BestPractice1.findItemsWithNameContaining(BestPractice1.java:84)
at mm.AldspServlet.accessAldsp(AldspServlet.java:52)
at mm.AldspServlet.doGet(AldspServlet.java:34)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:743)
Truncated. see log file for complete stacktrace
java.rmi.UnmarshalException: failed to unmarshal interface com.bea.ld.QueryResult; nested exception is:
java.lang.ClassNotFoundException: Failed to load class com.bea.ld.server.QueryResultImpl
at weblogic.rjvm.ResponseImpl.unmarshalReturn(ResponseImpl.java:201)
at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:315)
at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:250)
at com.bea.ld.Server_ydm4ie_EOImpl_815_WLStub.executeFunction(Unknown Source)
at com.bea.dsp.dsmediator.client.XmlDataServiceBase.invokeFunction(XmlDataServiceBase.java:312)
Truncated. see log file for complete stacktrace
java.lang.ClassNotFoundException: Failed to load class com.bea.ld.server.QueryResultImpl
at weblogic.rmi.utils.WLRMIClassLoaderDelegate.loadClass(WLRMIClassLoaderDelegate.java:203)
at weblogic.rmi.utils.WLRMIClassLoaderDelegate.loadClass(WLRMIClassLoaderDelegate.java:128)
at weblogic.rmi.utils.Utilities.loadClass(Utilities.java:308)
at weblogic.rmi.utils.Utilities.loadClass(Utilities.java:344)
at weblogic.rjvm.MsgAbbrevInputStream.resolveClass(MsgAbbrevInputStream.java:395)
Truncated. see log file for complete stacktrace
>

 

ALDSP 2.1 vs QName

Ironically, I can get Tomcat to run the test ALDSP servlet.  The only wrinkle is that I cannot place weblogic.jar in the WAR because it contains servlet API classes and Tomcat will not load such JARs in conformance with the servlet specification.  The workaround is to put weblogic.jar in Tomcat's shared/lib directory.

2006-04-10

ALDSP 2.1 vs QName

We had a test suite that exercised some ALDSP data services.  The suite had been ported to run successfully on ALDSP 2.1, under JVM 1.4.  But when we tried to run the suite under JVM 1.5, all the tests failed with an EOFException on the client side.  The server side reported a class serialization version incompatibility on QName.  Again.  This was supposed to be fixed under ALDSP 2.1.  Apparently not.

Actually, the release notes for ALDSP 2.1 do not specifically mention that Java 1.5 is supported, but they do say that WLS 9.x are now certified as ALDSP clients.  WLS 9.x demands Java 1.5.  I tried writing a servlet to test whether that WLS 9.x can now be used as clients -- no go.  Same exception:

<Apr 11, 2006 5:22:31 PM MDT> <Error> <RJVM> <BEA-000503> <Incoming message header or abbreviation processing failed
java.io.InvalidClassException: javax.xml.namespace.QName; local class incompatible: stream classdesc serialVersionUID = 4418622981026545151, local class serialVersionUID = -9120448754896609940
java.io.InvalidClassException: javax.xml.namespace.QName; local class incompatible: stream classdesc serialVersionUID = 4418622981026545151, local class serialVersionUID = -9120448754896609940
        at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:463)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1521)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1435)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1264)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
        at weblogic.rjvm.ClassTableEntry.readExternal(ClassTableEntry.java:33)
        at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1686)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1644)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
        at weblogic.rjvm.InboundMsgAbbrev.readObject(InboundMsgAbbrev.java:65)
        at weblogic.rjvm.InboundMsgAbbrev.read(InboundMsgAbbrev.java:37)
        at weblogic.rjvm.MsgAbbrevJVMConnection.readMsgAbbrevs(MsgAbbrevJVMConnection.java:212)
        at weblogic.rjvm.MsgAbbrevInputStream.readMessageContext(MsgAbbrevInputStream.java:237)
        at weblogic.rjvm.ConnectionManager.dispatch(ConnectionManager.java:744)
        at weblogic.rjvm.t3.T3JVMConnection.dispatch(T3JVMConnection.java:782)
        at weblogic.socket.NTSocketMuxer.processSockets(NTSocketMuxer.java:105)
        at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:32)
        at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224)
        at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
>

 

2006-04-07

Headless Eclipse Ant Builds

If you want to run an Ant build within the Eclipse environment, you can launch Eclipse headless as follows:

@echo off
setlocal

set JAVA="c:\esidev\jdk1.5.0_06\bin\java.exe"
set ECLIPSE="c:\esidev\eclipse3.1.x\startup.jar"
set WORKSPACE="c:\work\workspace"
set BUILDFILE="%WORKSPACE%\esi.environment utilities\rebuild-all.ant.xml"

@echo on
%JAVA% ^
  -cp %ECLIPSE% ^
  org.eclipse.core.launcher.Main ^
  -application org.eclipse.ant.core.antRunner ^
  -data %WORKSPACE% ^
  -buildfile %BUILDFILE% ^
  %*

This can come in handy if the Ant script uses some of the Eclipse tasks or if the build relies upon Eclipse's built-in build processes.

2006-04-06

Eclipse TreeViewer Selections

Using Eclipse RCP, I noticed that whenever I refreshed a TreeViewer the selection was lost.  Reading the code, I found out that RCP was attempting to preserve the selection but it just wasn't working.  After further experimentation, I noticed that treeViewer.setSelection(treeViewer.getSelection()) does not work at all.  After a lot of fiddling around, I finally tracked down the problem:  one of my model objects had a broken Object.equals() method that erroneously thought that the object was equal to the tree's root object.  Needless to say, this caused the RCP framework to get very confused.

Having worked through all that, I was pleasantly surprised to find that the TreeViewer gracefully handles modifications to the model without collapsing the tree view or losing its selection.  It uses the registered IElementComparer to perform the equality test (naturally, the default comparer uses Object.equals()).

One thing to note:  if you do set an element comparer on a tree viewer, then for some reason the getElements() method on the ITreeContentProvider will be called.

2006-04-03

Wikipedia vs. the Generic LCS Delta Algorithm

Wikipedia offers the following method to compute the longest common subsequence of two sequences (using the so-called "Generic LCS Delta" algorithm):

LCS-Delta(X,Y)
m <- LENGTH[X];
n <- LENGTH[Y];
for i <- 1 to m, do c[i,0] <-0;
for j <- 0 to n, do c[0,j] <-0;
b <- c;
for i <- 1 to m, do {
    for j <- 1 to n do {
         if (xi = yj) {
             c[i,j] <- c[i-1,j-1]+1;
             b[i,j] <- "UP-LEFT";
         }
         else if (c[i-1,j] >= c[i,j-1]) {
             c[i,j] <- c[i-1,j];
             b[i,j] <- "UP";
         }
         else {
             c[i,j] <- c[i,j-1];
             b[i,j] <- "LEFT";
         }
    }
}
return c and b

This algorithm fails for various trivial cases, such as (X, Y) = ({1}, {-1}), (X, Y) = ({1}, {}), and (X, Y) = ({}, {1}).  The problem is that the highlighted lines should read as follows:

for i <- 1 to m, do c[i,0] <- "LEFT";
for j <- 0 to n, do c[0,j] <- "UP";

If you neglect this initialization, differences at the beginning of the sequence are ignored.

Actually, I am probably being too hard on the wikipedia article since it suggests that the differences be computed from the LCS array using the following, somewhat confusing, algorithm:

The following algorithm will give the list of edits needed to make Y equal to X (the diff algorithm):

Notation: [n,m] refers to a LCS component at X[n] and Y[n]

Assumptions:

   The LCS as found by findLCS() is placed on a stack moving from the lower-right corner and
   following the direction arrows to form the LCS.

oldElem <---- [-1,-1]
while stack is not empty
   elem <---- pop from stack
   // diff does not require LCS components but add to list here if desired
   for i=oldElem[n] to elem[n]
        add delete X(i) from list of edits
   for i=oldElem[m] to elem[m]
        add insert Y(i) to list of edits

The change that I suggest makes it possible to recover the LCS by reversing the links in the table rather than using a stack.  I have an implementation in Java.

2006-03-31

Eclipse TreeViewer

I tried an experiment to explore the behaviour of Eclipse TreeViewers when their input model was changed.  I was hoping that if the new model was equivalent to the old using equals(), then the tree would not collapse and lose its selection.  No such luck.  The new model must be '==' the old model to retain tree state.

2006-03-29

Eclipse Bundles vs. BEA SDO Classloaders

I had a set of Eclipse plug-ins, one of which contained BEA's SDO implementation and another that used it.  Most of the time, SDO objects could be loaded and manipulated without problems.  But when I tried this snippet:

String graphXml = originalObject.getDataGraph().toString();
DataGraph newGraph = new DataGraphImpl(graphXml);

I got the exception:

SDO generated classes for: {http://www.mm.com/xmlns/2006/esi.manage/api/}DataModelis not in the classpath

The fix was to adjust the manifest for the SDO plug-in so that it would look in dependent plug-ins when trying to load classes.  The relevant entry in MANIFEST.MF was:

Eclipse-BuddyPolicy: dependent

2006-03-24

Eclipse RCP Forms

On forms at least, if you create a composite but do not associate a layout with it, none of the component widgets will appear within the composite.

If you are using a managed block on a form, but you do not set the text ("title") of the form to anything, the detail panel will not resize properly when the window is resized.  The detail panel will remain a fixed size and a scrollbar will appear on the bottom.

Many types of changes (like changing the form text to fix the detail panel resizing problem, above) do not take full effect if you are relying upon hot code downloading in a debugging session.  You have to exit the application and restart it.

2006-03-22

Eclipse RCP Forms

If you are using a MasterDetailBlock, if you try to create content for an IDetailsPage setting the marginHeight on a Section to anything other than zero, the content of the whole section will be displayed incorrectly.  e.g.

    public void createContents(Composite parent) {
        TableWrapLayout layout = new TableWrapLayout();
        layout.topMargin = 5;
        layout.leftMargin = 5;
        layout.rightMargin = 2;
        layout.bottomMargin = 2;
        parent.setLayout(layout);

        FormToolkit toolkit = _managedForm.getToolkit();
        Section section = toolkit.createSection(parent, Section.DESCRIPTION);
        toolkit.paintBordersFor(section);
        section.marginWidth = 10;
        section.marginHeight = 5; // don't try to do this
        section.setText("Lookup Types");
        section.setDescription("Some description...");
        ...

Also, if you do not set the layout on the parent of a details page, the details won't show up at all.

2006-03-20

BEA Workshop vs. EsiPlatformDataDS Build Process

The problem was that the JAR file wlsdo.jar was not accessible to Workshop.  It is not clear why this is the case.  Three solutions were identified:

  1. Add wlsdo.jar to the application in the Libraries folder.
  2. Add wlsdo.jar as an additional classpath entry in the application preferences.
  3. Add wlsdo.jar as an additional classpath entry in C:\esidev\bea\weblogic81\workshop\Workshop.cfg.

We chose #3.  #1 had the problem it creates a copy of the JAR, so it just creates one more place that needs to be updated if we ever change versions.  #2 had the problem that we could not locate where the additional entry was being stored -- it was not anywhere within the application source directory.

Another problem we noted was that if you attempt to build a data service project when some of the underlying XSD files are missing, then you will get a cryptic error message suggesting that you verify that the temp folder is writable.  In our case, the XSD files were being copied into the project by a previous step.  If you missed that step, the error message was not much good a reminding you to do the copy.  The same 'temp folder' message will also appear if the APP-INF/lib directory does not exist.

2006-03-17

BEA Workshop vs. EsiPlatformDataDS Build Process

I discovered today that you cannot build our EsiPlatformDataDS project from within BEA workshop after performing a 'clean'.  The error is 'package commonj.sdo does not exist'.  If you run our automated build within Eclipse for that project, then BEA workshop will start working as well -- until the next 'clean'.

Further investigation is needed to figure out why this is happening.

On a related note... don't give BEA Workshop focus while running a build of the application from outside (e.g. from within Eclipse).  If you do, then workshop will note that project files have changed and will kick off a build of its own.  The two builds will conflict and neither will work properly.

2006-03-16

Oracle 9.2 Client Installer

Under Windows at least, the Oracle 9.2 Client Installer prepends a JRE 1.3.1 to the front of the system PATH.  This changes the ambient JRE and thus has the potential to break various Java components -- especially those that need a more current (i.e. not totally obsolete) version of Java.  A quick solution is to move Oracle's PATH entries to the end of the PATH instead of at the beginning.

Universal Data Link Files

A quick to construct OLE DB or ODBC connection strings on Windows is through Universal Data Link or .UDL files.  Create an empty file with a .UDL extension.  Then open it, which will bring up a nice UI for configuring the data source.  When finished, the file will contain the appropriate connection parameters.

2006-03-15

Apache Tomcat

I noticed that when I was deploying (and especially reploying) WAR files to Apache Tomcat, sometimes the deployment would not be complete.  In particular, the exploded WAR directory only contained a small subset of the files in the WAR.  Furthermore, when I undeployed the WAR, portions of the exploded directory would not be deleted.  I found a solution, however.  Edit the CONTEXT element in context.xml to have the attribute antiJARLocking="true".  You can do this for the context descriptor for the individual application (if any), or by editing the global context.xml in the Tomcat configuration directory.

2006-03-14

Eclipse Forms

The Eclipse Forms Programming Guide is a tutorial about creating forms in Eclipse.  One of its first example creates a text box that is supposed to have a 'flat' border.  However, if you actually run the sample code, it does not work -- no border is drawn.  After much gnashing of teeth, I determined that a line of code was missing from the example:

toolkit.paintBordersFor(form.getBody());

You must use this incantation to get field borders drawn.

2006-03-13

Wiki Password Lists

When storing passwords in protected HTML files, I have routinely set the text to black on black so that the passwords cannot be read by people wandering by, and also so that they are not readable when printed.  Some wikis, don't allow black on black text, so here is another cheesy alternative... create a hyperlink that pops up the the password, which is trivially encoded to stymie the passers-by:

<a href="javascript:alert(String.fromCharCode(112,97,115,115,119,111,114,100));">?</a>

Here is a snippet to URL-encode a password using a Javascript console:

var p="password"; var s = ""; for (var i = 0; i < p.length; ++i) { s += (i>0?",":"") + p.charCodeAt(i) }; s;

2006-03-09

Oracle 10g

Oracle now has a "recycle bin" for dropped tables.  A DROP command now just renames a table to a long obnoxious name and marks it a being in the recycle bin.  To delete it permanently, you must either use DROP TABLE XXX PURGE or PURGE RECYCLEBIN.  A DBA can use PURGE RECYCLEBIN_DBA to purge all recycle bins for all users.

This functionality is known as the "flashback feature".

2006-03-02

Eclipse vs BEA ALDSP Client JARs

For reasons unknown, occasionally if I rebuild an ALDSP Client JAR in Workshop, then refresh a project which references the JAR in Eclipse, Eclipse still does completely pick up any new classes and packages.  The code completion will recognize them, but the compiler does not.  Closing and re-opening the Eclipse project corrects the situation.

BEA ALDSP WTF

Here is the final result.  ALDSP uses the first function in a data service as the submission function, regardless of which function was used to actually retrieve the data.  Therefore, that function must conform to the ALDSP rules, which are:

  1. The return type must match the return type of the data service (like all functions in a data service).
  2. The return type must have cardinality 1 or 0..1.
  3.  (i.e. a declaration like:  declare function submitter(args) as ReturnType*).

In addition, you must build the application before any submissions will work, unlike reader functions which will work right away.

The second requirement is not entirely obvious because by default the Workshop generates reader functions with cardinality 0..*.  However, somewhere in the ALDSP machinery this case is detected and the infrastructure quietly wraps a new cardinality 1 element around the result, typically named 'ArrayOfYourType' (or sometimes 'YourTypeArray' for nested elements).

I don't understand why ALDSP requires a wrapper element in the 0..N case, but not the 0..1 case.

Build Issues

Another thing I discovered is that if you accidentally add a BEA function pragma to a function (e.g. by copy-and-paste from another function) they will work when you test from within workshop.  But when you go to build the application you will get an error message like:

ERROR: workflow3.ds:1:: [ld:DsTest/MmSandbox/workflow3.ds]: The namespace of the function "{http://www.w3.org/2004/07/xquery-local-functions}wraprow" with arity 1 does not match the expected namespace "ld:DsTest/MmSandbox/workflow3".

The Workshop XQuery editor will complain about any functions (including local functions) in a data service file whose namespace does not match the target namespace of the service, but this warning is spurious as the file will still build, deploy, and function properly.  If you want to avoid the warning, declare the function in the target namespace instead.

Apparently, using "build application" in BEA Workshop is not sufficient for the environment pick up certain changes.  I moved a data service file from ".../schemas//bestpractice.ds" to ".../bestpractice.ds".  The environment did not pick up the change even after I did "build application" and even after a "clean" followed by a "build".  Only after I chose "Build EAR" was the change noticed.

Furthermore, some classes of changes (e.g. renaming a data service) may not be picked up by the Workshop test tool until after exiting and re-entering the Workshop application.

2006-03-01

BEA ALDSP WTF

I was struggling with submitting updated data graphs through BEA.  My data source looked something like this:

declare function tns:getWrapper() as element(ns0:TestWrapper) {
    let $TEST_TABLE := ns1:TEST_TABLE()[ID=1]
    return
      
        {fn:data($TEST_TABLE/ID)}
        {fn:data($TEST_TABLE/NAME)}
      
};

where ns1:TEST_TABLE was a physical data source.  However, whenever I tried to submit changes to this function, I would get the dreaded "no lineage" exception.  I tried various other forms for the data source, such as:

declare function tns:getWrapperForUpdate() as element(ns0:TestWrapper)* {
    for $TEST_TABLE in ns1:TEST_TABLE()
    return
      
        {fn:data($TEST_TABLE/ID)}
        {fn:data($TEST_TABLE/NAME)}
      
};

Depending upon how aggressive I got with the various wrapping elements, the submits may or may not work.  Then...

I discovered that the data service test tool in BEA Workshop supported submits.  So I tried using it to test various combinations.  One thing I noticed right away was that when I pressed the 'edit' button, the data would be retrieved in a completely different form with various "holder" elements supplied automatically.  For example, the first data service shown above would have all of its data returned in a wrapping TestWrapperDocument element.  The second data service had ArrayOfTestWrapperDocument and TestWrapperArray elements introduced throughout the tree.  Now comes the strangest part...

After messing around with various submissions through the test tool, suddenly submits that formerly didn't work started working.  Even my external Java client started working.  Apparently, the mere act of testing submissions through the test tool is enough to either change internal configuration information or perhaps even generate more classes that makes things work.  I have been unable to determine the exact sequence of events to make this magic happen.  More investigation is needed, and it seems important to build the application and/or the EAR after getting a successful submission.  Stay tuned.

Apache Tomcat 5.5 Java Options

If you try to configure debugging using the Tomcat 5.5 monitor/configuration applet, make sure that you separate the individual options under Java/Java Options with newlines (e.g. put -Xdebug on a separate line from -Xrunjdwp).  If you don't, then the settings are quietly ignored (or, at least, I couldn't find any evidence of their failure).

Oxygen SOAP Analyser vs. Eclipse

If you attach a debugging session to a web server, set a breakpoint in a web service, and then invoke the web service from the Oxygen SOAP analyser, a dialog will come up saying that the analyser is awaiting a response from the server.  However, the server is not going to respond because the breakpoint is hit.  The dialog is modal, so you can't do anything.  To make matters worse, the cancel button does nothing.  The only way out of this situation is to kill the Eclipse process.

2006-02-28

Apache Axis

I was getting a strange error message from Axis 1.3 stating that there was no deserializer for the type xs:string (or, alternatively, that there was no serializer for java.lang.String).  It turned out that the problem was that I had previously deployed a web service that had custom serializers but had then changed the JAR so that it no longer contained the classes that supported them.  In addition, I had not undeployed the web service that reference those serializers.  Apparently, if Axis is unable to load any custom serializer, it fails to load all serializers -- including the built-in ones.  The moral of the story is that if you see strange serialization errors, go check Axis' server-config.wsdd for dead entries.

2006-02-24

LDAP Specifications

LDAP is defined in RFC 1777.  LDAP search filter syntax is documented in RFC 1960.

BEA ALDSP

Today Wing found a problem when trying to write back document changes using BEA ALDSP.  The error message stated that the heritage of the changes was ambiguous.  Viewing the query plan for the relevant data source, we found a warning stating that the type of the result did not match the type of the document.  Further investigation revealed that if we changed the return type of the data source function from 'Activity' to 'Activity*', then everything worked -- except that now the document was wrapped in one of BEA's famous generated 'array' types.  It turns out that the expression that was computing the return result implied a maxOccurs of "unbounded", e.g.  for $activity in ns0:getActivity().  We knew, however, that this function always returned no more than one result.  Thus, the problem was solved by changing the expression to let $activity := ns0:getActivity()[1].  Interesting that the compiler was correctly identifying that the expression actually returned Activity* but didn't complain when the function was declared as returning Activity.

2006-02-23

XMLBeans vs HTTP Requests

I saw a strange problem where one of the XMLBeans parse functions failed intermittently when parsing the input stream of an HTTP request.  The exception is:

Caused by: org.xml.sax.SAXParseException: Unexpected end of file after null
	at com.bluecast.xml.Piccolo.reportFatalError(Piccolo.java:1003)
	at com.bluecast.xml.Piccolo.reportFatalError(Piccolo.java:990)
	at com.bluecast.xml.Piccolo.yyerror(Piccolo.java:1302)
	at com.bluecast.xml.Piccolo.yyparse(Piccolo.java:1403)
	at com.bluecast.xml.Piccolo.parse(Piccolo.java:702)
	at com.bea.xbean.store.Root$SaxLoader.load(Root.java:735)
	... 29 more

A quick web search revealed that others had hit this too:

Apache JIRA issue XMLBEANS-226: Exception "Unexpected end of file after null"

The JIRA issue notes that the problem is in the Piccolo parser.  Apparently, that parser does not close the input stream once parsing is complete.  However, it does close the stream the next time you do a parse (which may not happen for an indefinite period of time).  In the absence of a fix from the Piccolo team, the workaround is to close the input stream yourself.  Unfortunately, that causes problems in a subsequent parse because it will attempt to close the stream again (throwing another exception).  Thus, you must wrap the stream with a class that overrides the close method to be tolerant of multiple closes.  That workaround works.

2006-02-22

Eclipse Plug-in Development

I've hit this issue before, but it took much effort to rediscover the answer, so I'm writing it down this time...

When you create a plug-in that simply packages and re-exports pre-existing JAR files, make sure that the following things are true:

  1. the JARs are all listed in the project build path ("Libraries" tab)
  2. the JARs have all been exported in the project build path ("Order and Export" tab)
  3. the JARs are all listed in the 'Classpath' list in the manifest ("Runtime" tab)
  4. the JAR packages that you wish to export (normally all of them) are listed in the export listof the manifest ("Runtime" tab)
  5. the JARs are all selected in the binary build list of the manifest ("Build" tab)

I had done all of these steps but #2.  A dependent plug-in complained that package names could not be resolved -- even though all other signs indicated that the packages were accessible.

2006-02-21

BEA XQuery

BEA's implementation of XQuery does not support recursion.  If you try it, you get an exception like:

weblogic.xml.query.exceptions.XQuerySystemException: {bea-err}SYS006: Function {lib:DsTest/WorkItemHierarchy/hierarchy}factorial is recursive; this is not supported (sorry)
	at weblogic.xml.query.operators.UserDefinedFunction.codeGenRecursiveFunction(UserDefinedFunction.java:174)
	at weblogic.xml.query.runtime.core.RecFuncIterator.fetchNext(RecFuncIterator.java:69)
	at weblogic.xml.query.iterators.GenericIterator.next(GenericIterator.java:109)

BEA SDO

BEA's SDO implementation does not appear to stand alone.  Under certain circumstances where an SDO graph is modified, the change log contains XPath expressions of sufficient complexity that the BEA SDO stack elects to invoke their full XQuery implementation.  In particular, a data graph was modified and converted to XML.  Its change summary looked like this:

<changeSummary>
  <Activity com:ref="/Activities/Activity[10]">
    <Required>1</Required>
  </Activity>
  <Activity com:ref="/Activities/Activity[11]">
    <Required>1</Required>
  </Activity>
...

When trying to rematerialize the graph using DataGraphImpl.parse(), an exception was thrown:

java.lang.UnsupportedOperationException: This query is too complex to be processed.
	at com.bea.xbean.store.XqrlDelegate.invoke(XqrlDelegate.java:70)
	at com.bea.xbean.store.XqrlDelegate.compilePath(XqrlDelegate.java:39)
	at com.bea.xbean.store.Path$XqrlPathImpl.create(Path.java:265)
	at com.bea.xbean.store.Path.getCompiledPath(Path.java:169)
	at com.bea.xbean.store.Path.getPath(Path.java:81)
	at com.bea.xbean.store.Path.getPath(Path.java:58)
	at com.bea.xbean.store.Path.select(Path.java:43)
	at com.bea.xbean.store.Cursor.selectPath(Cursor.java:2898)
	at com.bea.xbean.values.XmlObjectBase.selectPath(XmlObjectBase.java:395)
	at com.bea.xbean.values.XmlObjectBase.selectPath(XmlObjectBase.java:379)
	at com.bea.sdo.impl.DataObjectHandler.selectSdoPath(DataObjectHandler.java:1323)
	at com.bea.sdo.impl.DataObjectHandler.get(DataObjectHandler.java:212)
	at com.mm.platform.xbean.impl.ActivitiesDocumentImpl.get(Unknown Source)
	at com.bea.sdo.impl.DataGraphImpl.parseChildren(DataGraphImpl.java:520)
	at com.bea.sdo.impl.DataGraphImpl.parseDataGraphDocument(DataGraphImpl.java:451)
	at com.bea.sdo.impl.DataGraphImpl.(DataGraphImpl.java:88)
	at com.bea.sdo.impl.DataGraphImpl.(DataGraphImpl.java:96)

At first I tried simply adding BEA's xqrl.jar, which contains their XQuery engine.  However, the behaviour did not change.  Further experimentation revealed that the JARs wlxbean.jar was also necessary.  However, this combination only pushed the problem deeper:

java.lang.RuntimeException: weblogic/apache/xerces/impl/xs/SchemaSymbols
	at com.bea.xbean.store.XqrlDelegate.throwRuntimeException(XqrlDelegate.java:59)
	at com.bea.xbean.store.XqrlDelegate.invoke(XqrlDelegate.java:81)
	at com.bea.xbean.store.XqrlDelegate.compilePath(XqrlDelegate.java:39)
	at com.bea.xbean.store.Path$XqrlPathImpl.create(Path.java:265)
	at com.bea.xbean.store.Path.getCompiledPath(Path.java:169)
	at com.bea.xbean.store.Path.getPath(Path.java:81)
	at com.bea.xbean.store.Path.getPath(Path.java:58)
	at com.bea.xbean.store.Path.select(Path.java:43)
	at com.bea.xbean.store.Cursor.selectPath(Cursor.java:2898)
	at com.bea.xbean.values.XmlObjectBase.selectPath(XmlObjectBase.java:395)
	at com.bea.xbean.values.XmlObjectBase.selectPath(XmlObjectBase.java:379)
	at com.bea.sdo.impl.DataObjectHandler.selectSdoPath(DataObjectHandler.java:1323)
	at com.bea.sdo.impl.DataObjectHandler.get(DataObjectHandler.java:212)
	at com.mm.platform.xbean.impl.ActivitiesDocumentImpl.get(Unknown Source)
	at com.bea.sdo.impl.DataGraphImpl.parseChildren(DataGraphImpl.java:520)
	at com.bea.sdo.impl.DataGraphImpl.parseDataGraphDocument(DataGraphImpl.java:451)
	at com.bea.sdo.impl.DataGraphImpl.(DataGraphImpl.java:88)
	at com.bea.sdo.impl.DataGraphImpl.(DataGraphImpl.java:96)

You can see from the stack trace that BEA's own version of Xerces is required.  This, and the classes that support it, are available in weblogic.jar -- a 50 megabyte wonder.  It would appear that the whole WebLogic infrastructure needs to be pulled into the application just to rematerialize an SDO data graph object.  Thus, BEA's SDO does not appear to be "standalone".  Looking over the code for com.bea.xbean.store.Path, I can see that it attempts to use the built-in XBean XPath engine, falling back to Jaxen and XQRL if necessary.  My casual inspect was not enough to determine the circumstances under which each occurred.

2006-02-02

Embedded Tomcat

When using embedded Tomcat, the error message:

HTTP/1.1 400 No Host matches server name 127.0.0.1

can be caused by neglecting to start a context path with a slash.  That is, don't use this:

Context context = embedded.createContext("mycontext", webAppBase);

use this:

Context context = embedded.createContext("/mycontext", webAppBase);

 

2006-01-27

Blog Archive