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

2010-11-25

Hibernate User Types vs. Field Access

In Hibernate (3.2), one can define persistence entity properties that have customized types. There is, however, a bug that arises if the property is mapped with an access type of field. In that circumstance, the following two problems occur if the entity is accessed through a proxy:

  • a reference to the property through a getter method will not trigger initialization of the proxy
  • even if the proxy has been initialized, a getter method will still return an uninitialized value instead of the calculated custom field value (in a debugger, one can see that the proxy is initialized and has a properly loaded target object with the correct custom value -- but the getter returns the uninitialized value just the same)

These problems disappear if the custom-valued property is defined with property access (i.e. getter/setter).

Regular, non-custom properties do not exhibit these problems. I do not know whether this problem has been fixed in later versions of Hibernate. I could find no mention of the problem on the 'net. But then again, Hibernate 3.2 is all but obsolete -- I'm just stuck with it right now.

The second problem may be partly a consequence of another proxy pitfall: proxy field values never change -- even after the proxy has been initialized. The field values will be whatever the no-argument constructor assigns to them (typically zeroes and nulls). You must access proxied properties through this or a getter/setter.

There is a consequence of uninitialized proxy fields that had never occurred to me, but which popped up repeatedly while I was Googling for the original custom-type problem. Uninitialized proxy fields will be particularly apparent in equals() methods (which are virtually impossible to get correct in a Hibernate context anyway, but that is a story for another day). It is extremely common to see code like this._field == that._field in equals() methods. If that is a proxy, this code will not work since the wrong field value will be obtained. Advance Hibernate Proxy Pitfalls on the Xebia blog is one of many examples of discussion on this topic.

2010-11-11

Google Refine

Freebase Gridworks is now called Google Refine, a consequence of Google's acquisition of Metaweb.

2010-10-30

Google Omaha

Google has open-sourced their software updater, known as Omaha.

2010-09-23

Heavy-Cursor Code

Heavy-cursor code refers to misplaced code that, for architectural reasons, really belongs somewhere else. It is "heavy" as in: "I know I should have put that code in another class, but I was tired and the cursor was just too darned heavy to move."

Heavy-cursor code is a software analogue to a glacial erratic. It is the enemy of separation of concerns.

2010-09-16

Intelligence

Philosophers debate the definition of intelligence. Especially when qualified by the adjective artificial.

Intelligence is the ability to achieve ill-defined goals.

Go figure.

SQL Server vs IDENTITY ROLLBACK

SQL Server 2005 and 2008 support the concept of IDENTITY columns, which are integer columns that are automatically assigned a unique sequence number when rows are inserted into the table. Each table has a so-called IDENT_CURRENT value which remembers the last IDENTITY issued.

Curiously, IDENT_CURRENT values do not participate in transactions. Thus, once an identity value has been issued, it is issued permanently -- even if the containing transaction is rolled back. This is still true even if the transaction isolation level is serializable.

This makes one wonder how identity values are generated...

Here is some SQL that illustrates the problem.

CREATE TABLE zot (x INT IDENTITY, y INT)

GO

BEGIN TRANSACTION
INSERT INTO zot (y) VALUES (0)
SELECT 'first id: ', x FROM zot
ROLLBACK TRANSACTION

BEGIN TRANSACTION
INSERT INTO zot (y) VALUES (0)
SELECT 'second id: ', x FROM zot
ROLLBACK TRANSACTION

GO

DROP TABLE ZOT

The queries show that the first IDENTITY issued was 1 and the second was 2.

2010-08-19

Patent Trolls Beware

Like many (most?) developers, I've always thought that the software patent system is broken beyond repair. But, I didn't know whether to laugh or cry when I came across IBM's patent application 20070244837, "SYSTEM AND METHOD FOR EXTOREXTRACTING VALUE FROM A PORTFOLIO OF ASSETS". It would be "laugh" if this were to be used only defensively. But "cry" seems appropriate when one reads stories like how IBM "extracted value" from Sun.

We need shed no tears for Sun which had turned to IP trolling as a survival strategy. The attempt "extracted value" (unlike SCO), but ultimately failed to keep Sun alive. Oracle is disbanding Sun units all over the place, but apparently the IP trolling department is safe.

Should Oracle succeed, I'd love to see IBM get their patent, jump in and claim a royalty along with infringement damages. Or perhaps not -- be careful for what you wish!

2010-08-11

Y-Combinator in Haskell

I wrote about the Y-combinator before. Recently, I tried to express the Y-combinator in Haskell, thus:

y f = fg fg
      where fg g = f (g g)
To my surprise, I got an error message (from GHC):
Occurs check: cannot construct the infinite type: t = t -> t1

To fix it, I had to introduce a helper type to break the direct cycle in the type definition:

newtype Hold a = Hold (Hold a -> (a -> a))

y f = fg (Hold fg)
  where fg hg@(Hold g) = f (g hg)

This worked. Armed with this definition, I could now implement the factorial function in terms of the Y-combinator:

f r n = if n < 2 then 1 else n * (r (n - 1))

:type y f
-- (Num t, Ord t) => t -> t

y f 10
-- 3628800

2010-08-07

akka

akka brings Erlang-style processes (actors) and Clojure-style STM to Scala and Java.

2010-06-22

Debugging Output in T-SQL

Here is a useful way to get debugging output while using SQL Server T-SQL:

DECLARE @message NVARCHAR(MAX)
SELECT @message = (
  SELECT something, andSomethingElse
  FROM someTable
  FOR XML AUTO
)
SELECT @message = REPLACE(@message, '><', '>'+CHAR(13)+'<')
RAISERROR(@message, 16, 1)

It is pretty cheesey, but it works in difficult contexts (e.g. restricted privileges, many tiers between you and the SQL server, unit tests that run in rolled back transactions).

2010-06-10

Apache CXF (née XFire)

XFire, the SOAP engine, is now known as Apache CXF.

One advantage of CXF/XFire over Apache Axis is that the client supports NTLM using ambient credentials on Windows. This is because CXF uses the native JDK NTLM support, whereas Axis uses a pure Java reverse-engineered implementation of NTLM 1.0 (with no 2.0+ support on the horizon).

2010-06-08

Leading Slash vs. ClassLoader.getResource()

When using the Java API ClassLoader.getResource(), be sure that your resource path does not start with a slash. If you do, then the result will be null. This behaviour is different from Class.getResource(), where a leading slash has special meaning.

At least, this is how Sun's implementation behaves. The Javadoc for ClassLoader.getResource() is not too clear on this point (although the implication is there). I found this out by reading the source.

I found this problem while troubleshooting a pesky unit test that would work within Eclipse when run as a JUnit Plug-in Test, but would fail when run as a basic JUnit Test. It turns out that the Eclipse implementation of ClassLoader.getResource() is tolerant of the leading slash. Almost everywhere in the code base, the resource names were correct and did not have a leading slash. In the particular case in point, however, a leading slash had been inadvertently added -- a difficult mistake to spot.

2010-05-31

Scriba -> Seco

Scriba, the Mathematica-like document-centric scripting environment, is now known as Seco.

2010-05-24

Envjs, Claypool, Jaxer

Envjs is a Javascript library that emulates a browser scripting environment in an external Javascript engine like Rhino (the preferred target at this time), SpiderMonkey or V8. It was originally developed by John Resig so that he could use jQuery in non-browser scripting tasks. He also pointed out its possible utility in server-side Javascript.

Claypool is a Javascript application framework built up from jQuery. It runs in a Java Servlet container (it ships with Jetty).

Jaxer is billed as "the world's first Ajax server". It is a web application framework that allows one to write Javascript on the server side. Script elements in web pages can be annotated with the attribute runat="server". It provides libraries for all of the usual server-side facilities like security, database access, file system access, running external processes, etc.

2010-05-20

Sausalito

Sausalito is a scalable XML Database designed to run on the Cloud. It supports the creation of web applications where the business and database layers are both written in XQuery. The applications can be tested locally in Eclipse or deployed onto an AWS-based site.

The Sausalito group maintains the following open source projects:

2010-05-05

flot

They're everywhere! flot is another Javascript plotting package.

2010-04-09

jslibs

jslibs is a standalone SpiderMonkey-based Javascript host. It provides many libraries that provide OS access allowing one to use Javascript for general-purpose development.

nodejs

nodejs is a V8-based Javascript host that emphasizes event-driven network applications (like web servers). Using it, one can write Javascript on both the client and server sides.

2010-03-15

Java 6 XPath NamespaceContext Bug

In Java, one defines the namespaces for the XPath evaluator using the class NamespaceContext. In Java 6, the XPath evaluator does not consult the defined namespace context to interpret the default namespace. This despite explicit discussion of the default namespace in the Javadoc.

The workaround is to avoid using the default namespace in the XPath query.

It would appear that this somewhat surprising behaviour is consistent with the XPath 1.0 specification. Section 2.3 (Node Tests) states:

A QName in the node test is expanded into an expanded-name using the namespace declarations from the expression context. This is the same way expansion is done for element type names in start and end-tags except that the default namespace declared with xmlns is not used: if the QName does not have a prefix, then the namespace URI is null (this is the same way attribute names are expanded). It is an error if the QName has a prefix for which there is no namespace declaration in the expression context.

(emphasis is mine)

2010-03-11

SQL Server dbo Login Name

In SQL Server 2005, you cannot change the login name associated with the dbo user through the various management tools or by using sp_change_users_login. You must use the following command:

sp_changedbowner 'newloginname'

2010-03-10

BaseX

BaseX is a nice XML database engine and front-end that supports (full?) XQuery.

2010-03-07

Streaming Java XML Pipelines

The following example illustrates how to use the Java XML API to build a streaming XML pipeline that:

  1. reads an input stream (input)
  2. validates it against an XML schema (xsd1)
  3. transforms it using XSLT (xslt1)
  4. validates the result against another schema (xsd2)
  5. applies another XSLT transformation (xslt2)
  6. validates that result against yet another schema (xsd3)
  7. writes the result to a stream (output)

Here is the code:

SchemaFactory schemas = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

Schema schema1 = schemas.newSchema(new StreamSource(xsd1));
Schema schema2 = schemas.newSchema(new StreamSource(xsd2));
Schema schema3 = schemas.newSchema(new StreamSource(xsd3));

ValidatorHandler validator1 = schema1.newValidatorHandler();
ValidatorHandler validator2 = schema2.newValidatorHandler();
ValidatorHandler validator3 = schema3.newValidatorHandler();

SAXTransformerFactory transformers =
    SAXTransformerFactory.class.cast(TransformerFactory.newInstance());

Templates template1 = transformers.newTemplates(new StreamSource(xslt1));
Templates template2 = transformers.newTemplates(new StreamSource(xslt2));

Transformer transformer0 = transformers.newTransformer();
TransformerHandler transformer1 = transformers.newTransformerHandler(template1);
TransformerHandler transformer2 = transformers.newTransformerHandler(template2);
TransformerHandler transformer3 = transformers.newTransformerHandler();

validator1.setContentHandler(transformer1);
transformer1.setResult(new SAXResult(validator2));
validator2.setContentHandler(transformer2);
transformer2.setResult(new SAXResult(validator3));
validator3.setContentHandler(transformer3);
transformer3.setResult(new StreamResult(output));

transformer0.transform(new StreamSource(input), new SAXResult(validator1));

This code does not introduce any intermediate DOM trees, string buffers or temporary files (of its own that is -- no warranties are offered for the parser or the XSD and XSLT processors). The key part of this solution is its use of transformer and validator SAX handlers. Also note the use of so-called identity transformers at the start and end of the pipeline. Strictly speaking, the solution could be shortened slightly by using the validate method on a validator, but I present the code as is to emphasize the transformer's role as the "backbone" of the pipeline.

As far as I can tell, there is no StAX analog to this approach in Java 6. The transformation and validation APIs have not yet been updated to know about StAX input streams. The Javadoc for StAXResult makes a cryptic remark about how Transformer and Validator can accept a Result as input, but I think that this is just awkward wording -- those classes show no evidence of living up to that remark.

2010-02-23

Jespa

Jespa is a closed-source, pure Java Microsoft Active Directory client. It is being recommended by the JCIFS group as a replacement for the old JCIFS NTLM servlet filter. At the time of writing, Jespa is free to use for up to 25 users -- beyond that you need to purchase a license from IOPLEX.

The JCIFS SSO filter was discontinued since it used a "man-in-the-middle" implementation technique that is not compatible with NTLMv2. See the JCIFS FAQ on this subject.

If you are in a bind and still want to use the old JCIFS SSO filter, configure JCIFS to fall back to NTLMv1 using the system properties:

-Djcifs.smb.lmCompatibility=2
-Djcifs.smb.client.useExtendedSecurity=false

Also see the properties described in the JCIFS API documentation.

2010-01-21

Simple SQL Server Table Change Tracking

The following SQL Server script demonstrates a simple technique for maintaining a log of the changes made to a table. The main idea is embodied in the emphasized code.

CREATE TABLE zot
( X INT
, Y INT
)
GO

CREATE TABLE changeLog
( id INT IDENTITY
, time DATETIME
, tableName NVARCHAR(255)
, change NVARCHAR(MAX)
)
GO

CREATE TRIGGER TR_zot ON zot FOR INSERT, UPDATE, DELETE AS BEGIN
  INSERT INTO changeLog
    SELECT GETDATE(), 'zot'
    , COALESCE((SELECT * FROM DELETED FOR XML AUTO), '')
    + COALESCE((SELECT * FROM INSERTED FOR XML AUTO), '')
END
GO

INSERT INTO zot VALUES (1, 2)
INSERT INTO zot VALUES (3, 4)
INSERT INTO zot SELECT 4, 5 UNION SELECT 6, 7
UPDATE zot SET X=999 WHERE X < 4
DELETE FROM zot WHERE X=999
DELETE FROM zot

GO

SELECT * FROM changeLog
GO

DROP TABLE zot
DROP TABLE changeLog
GO

The result of this script shows what the change log entries would look like:

id time tableName change
1 2010-01-21 10:57:11.0 zot <INSERTED X="1" Y="2"/>
2 2010-01-21 10:57:11.0 zot <INSERTED X="3" Y="4"/>
3 2010-01-21 10:57:11.0 zot <INSERTED X="6" Y="7"/><INSERTED X="4" Y="5"/>
4 2010-01-21 10:57:11.1 zot <DELETED X="3" Y="4"/><DELETED X="1" Y="2"/><INSERTED X="999"Y="4"/><INSERTED X="999" Y="2"/>
5 2010-01-21 10:57:11.1 zot <DELETED X="999" Y="4"/><DELETED X="999" Y="2"/>
6 2010-01-21 10:57:11.1 zot <DELETED X="6" Y="7"/><DELETED X="4" Y="5"/>

2010-01-08

Windows 7 "All Tasks" View

Under Windows 7, you can open a handy All Tasks view by entering the following command in the Run dialog:

shell:::{ED7BA470-8E54-465E-825C-99712043E01C}

Windows Explorer will also display this view in any folder whose name contains that GUID (e.g. create a folder named all-tasks.{ED7BA470-8E54-465E-825C-99712043E01C}). Some bloggers call this "God Mode".

The All Tasks GUID is not presently included in the Microsoft's list of Canonical Names of Control Panel Items. This might be because the feature seems to be a bit unstable -- if I scroll to the bottom of the window quickly, Windows Explorer often crashes.

Blog Archive