Archive for Synformation

Problem with Oracle

While operating synformation together with an Oracle database (prior to version 10g), the following error can occur during page compilation:

FATAL ERROR IN TWO-TASK SERVER: error = 12571
ksedmp: internal or fatal error

This error is logged by Oracle in the user dump trace files. After this error has occurred, no more pages can be compiled. From the ACU client software, it looks like the system is locked up. Only a restart of the synformation server software will help temporarily.

Page compilation within synformation is triggered by altering a block or a page template. The error can be easily reproduced by first altering a page template or a global block, directly followed by altering a local block. This almost always has the consequence that the ACU client software locks up. It’s not possible to compile pages from other ACU clients after this error has occurred. The error can be forced also by changing global and local blocks from different ACU clients.

Since such an error hasn’t been observed on other databases, I assume that it’s a problem only for Oracle databases prior to version 10g. Apparently, the error can be prevented if a certain foreign key is dropped. I recommend that everyone who runs synformation on an Oracle database prior to 10g deletes this key. Executing the following statement will fix the problem:

ALTER TABLE "SYN_PAGE_SECTIONS"
DROP CONSTRAINT "FK_PAGE_SECTIONS_BLOCK_ID" CASCADE;

Deleting this key has no side effects on the operation of the system.

I know that error 12571 hints to a network timeout. It seems strange that dropping a foreign key constraint fixes the problem, but I’ve tried hard to find a fix that feels more logical. Everything else I tried did not fix the problem. I’m not really satisfied with the solution, in part because synformation has a heavily normalised data model, and this fix breaks the beauty. I guess I’ve to live with that. Maybe someone else knows something to ease my pain?

Comments

If something goes wrong

When you build a software system, something can go wrong. You have to plan for that. It can be a programming error, an operator error, or a situation you haven’t planned for. I’m pretty sure you have seen web pages giving you cryptic error messages, thus indicating that something went wrong. In many cases, the given error message is useful for a programmer, but seldom for the average web user.

Fatal error:
Call to undefined function: some_function() in
/srv/domain.com/httpdocs/content/mytheme/header.php
on line 42

As a web user, what does this error message tell you? Maybe you can understand it. But can you do something about it? You can’t fix it, you’re left alone on finding your way out, it’s not helping you. Why then show it to you at all? The reason is, it wasn’t intended for you to see it. This error message is only useful for the developer. But he hasn’t planned for exactly this type of situation. Okay, it’s a programming error. But that you have to see this error in a form like this is lack of planning for this type of situation. Everybody knows or can understand that it’s not a good idea to have a web user look at a web page indicating an error like the one I showed you. But it’s still what happens in many cases. Why? Is it laziness on behalf of the developers, lack of good test cases, lack of imagination, lack of time or budget, or not enough knowledge? I think it’s a little of everything. The book Defensive Design for the Web from 37signals might tell you nothing a web developer should know already, but it contains a nice check list at the end to make sure he doesn’t forget to apply his knowledge.

To assist the developer in handling all not handled situations, synformation provides the mechanism of an error page that is called via forward() whenever a not handled error occurs. This error page is a normal synformation page with one exception: within the logic of the error page, you have access to an error object that holds all the information about the error. If you don’t define an error page within synformation, you’ll get something like the cryptic error shown above. It’s worse actually, because it might contain a Java stack trace because synformation runs on the Java platform.

I can only think of one reason to display a technical error message within the web page: the page is produced for the developer or tester. In all other cases, the user should see something more friendly, something that gives him some information on what to do next. He should not leave our web site in frustration. That’s why a typical synformation error page should contain logic like this:

<%%
$variable = getVariable("error");
if (null != $variable) {
    $msg = $error.toString();
    print S("X-ERROR-ERRORPAGE");
    // There's no need to send an email when an ACU can see the error
    if (isDevelopment() || getCurrentUser().isMemberOf("ACU")) {
%>
<div id="infobox" class="infobox-info">
<h1><%%= R("ERROR-PAGE-HEADING") %></h1>
<p><%%= $msg %></p>
</div>
<%%
    } else {
        print S("X-INFO-WHAT-NEXT");
        sendMail(R("ADDRESS"), R("SUBJECT"), R("TEXT") + $msg);
    }
} else {
    print S("PAGE-NOT-CALLABLE");
}
%>

I will explain this code snippet. First, we have to find out if an error object actually exists. If it does, the users gets a friendly hint in his language that an unexpected error has occurred and we’re really sorry about that. If we are in development mode, or the user has logged in and he is a developer, the actual error message is displayed, too. If we have a normal web user, a text with options on what to do next is presented. An email is then sent off to the development team with all the technical information needed to reproduce and fix the error. In case no error object exists, this page was called without having an error. Maybe somebody typed in the URL in his browser. We tell him in friendly language, that this page is not intended to be used like that. We can also display some information on what to do next - he is already on our page, so why not keep him.

We all know that things can go wrong. But we should all care more for having an actual plan installed, if that happens. I’m not perfect in this regard either, so this post might help me as a reminder.

Comments

JavaWorld: Dynamic Webpages with JSON

There’s an interesting article on how to overcome the same origin policy used by modern web browsers. It’s a security policy that prevents JavaScript from accessing a location different from the one it was loaded from. Same location normally means same protocol, subdomain, and domain. The same origin policy is sometimes called same site policy. One of the reasons for having this policy is to fix security issues like cross site scripting.

Communication between the synformation server and the client web application takes place under the same origin policy. Whenever the client needs data from another service outside the synformation domain, the synformation server can act as a proxy for such requests, thus avoiding to circumvent the policy. If you don’t have a server to act as a proxy for you, then the technique described in this article might be of interest to you. From a security perspective, neither of the two approaches is inherently more safe.

Comments

New GWT Release 1.2.22

The Google Web Toolkit has a new stable release. You can read all about it here. It will be used for the new synformation web site, too.

I’ve started to use GWT since version 1.0 came out (August 25, 2006). It was easy to use and since I’m not very good at JavaScript programming, leave alone all the little things you have to know to make sure your JavaScript is compatible with all the different browsers, it was the right thing for me as a Java developer.

Integration with synformation is easy. I don’t use GWT’s RPC mechanism, but the JSON format for client-server communication. GWT finally supports sending requests with content-type application/x-www-form-urlencoded, which is how it’s normally done. On the server side, I can now use request.getParameter() instead of having to read the posted data directly. It’s really not a big deal, but more convenient. The new module com.google.gwt.http.HTTP provides the necessary functionality.

I’ve written a quick example. It’s available here. It sends formatting instructions to the server via JSON. The server formats the current time and sends the text back to the client. The relevant portion of the page is updated to display the current server time. Note that not the whole page is updated, only the text with the server time. That’s because client-server communication is done asynchronously in the background. Although it’s only a small example, it already has the complete communication architecture for RIAs.

Comments

Internationalisation

I’ve decided, that the new web site will support at least two languages: English and German. That’s because I have a little knowledge of both of theses languages. Developing for these two languages is nearly the same as developing for n languages (it’s not, but we assume this for now). So how do I support more than one language?

Synformation supports I18N in many ways. In fact, there are so many ways, that it can be confusing at times when you have to choose one of them for a specific project. A so called content object in synformation is an object that normally has its content (e.g. binary data like pictures, text) and all the meta-data that comes with it (e.g. date, language, valid-until, relationship to other objects) to describe it further. These content objects are normally used for articles, documents, user generated comments, etc. That’s why they have this name.

If I write an article for the web site, I will translate it into the other language and publish it. To decide which article has to be shown (the english or the german one), I can filter the articles by using a meta datum called language. In fact, this will work even if there is no corresponding german article for an english one, because the content used within one page will be filtered without considering the existence of a translated version (e.g. show the first 10 english articles in category Java starting today ordered by date published descending and having activated equals true, and belonging to at least one of the user groups where the current user belongs to). So content can be filtered for one language by simply selecting the appropriate language. When I want to, I can define a relationship between the english and the german article by setting a relationship of type is translation of between two articles. Using this relationship I can easily find corresponding articles in other languages. When we look at another content type (user comments for articles), it’s quite clear that a specific comment will exist for only one language. Ok, the content part was quite easy to solve.

What other language specific resources do we have? We’ll look at a Post comment form for now. There is a little text explaining what you can do, there are some input fields and their labels, and there is a button with some text to post the comment. In case something goes wrong, it would be nice to have a message in the same language explaining what to do and providing a way out. Java offers resource bundles to store language specific resources, but you have to have one file for each language. This makes translation of these language specific resources a little harder than necessary. I want to have one file (or in my case content object) with all the different languages. With some preprocessing I could build the resource bundles from this content object, but I will go with a JSON object. It has a technical name for the resource and an array with one element for each language, e.g.

"FORM-COMMENT-SUBMIT": ["send", "Senden"]

This approach will be used only for simple text resources without any markup. For more complex text objects (like terms of use with headings and other semantic markup) I’ll use full blown content objects.

By the way, synformation can execute logic embedded within these text resources and content objects. Sometimes, it’s pretty handy to be able to write something like this:

Copyright 2002-<%% print
new java.text.SimpleDateFormat("yyyy").format(getNow()); %>

Of course, this can be a security issue. Imagine that someone commenting on an article is able to embed arbitrary logic within a comment. This is where user groups and the rights management comes into play. But this would be a completely different topic.

I hope you’ve got a feeling for how I plan to tackle I18N with this project. And maybe you have some better ideas. I would really like to hear about them.

Comments

« Previous entries