You want DB2 to start up automatically at boot, so you use the official method and enable the fault monitoring system and then use db2iauto -on instancename to enable autostart.
On rebooting, DB2 isn’t started. You check /var/log/syslog and see:
Jun 13 15:37:05 servername kernel: [ 67.324105] db2fmcd[1357]
general protection ip:7fa9c68306c4 sp:7fff86c43150 error:0 in
libc-2.15.so[7fa9c67c2000+1b5000]
or something similar. Yes, ironically enough, the fault monitor has caused a general protection fault.
The solution:
The DB2 10.1 installer seems to attempt to enable DB2 Administration Server (DAS), which was used for the old DB2 Control Center that is no longer supported in DB2 V10. DAS causes the crash. To disable it:
/opt/ibm/db2/V10.1/bin/dasdrop system
Then I rebooted, and after a minute or so the fault monitor successfully started DB2.
Solution found on the developerWorks forums, summarized and reposted here for added visibility to search.
Seems to affect CentOS, Ubuntu Server and VMware DB2 V10.1 instances, on Intel i7 x86-64. Affects DB2 V10.1 Enterprise Server, DB2 Express-C, and probably other license variants. Does affect clean installs.
The problem: You have a web agent somewhere which uses LotusScript MessageBox to output an error message. However, the message doesn’t say which agent or database it’s being output by, so you need to locate the agent which is printing the text.
The solution: At the console,
set config AgentThreadDebug=1
tell http restart
The HTTP task will then display a debug for each web-triggered agent that starts or ends.
Obviously, you’ll want to turn this off when you’re done debugging.
My first XPages app is coming along nicely. Today I needed to add some cookie support, and discovered that the otherwise comprehensive Mastering XPages had no information on the topic. There’s a post on the Lotus Developer Domain, but it’s a bit vague and makes the whole thing look harder than it really needs to be.
I started by writing myself a quick Server Side JavaScript library to encapsulate the details. As always, I’m using the Revealing Module Pattern. Here’s the code:
var Cookies = (function () {
/**
* Get a cookie value as a Cookie object.
*/
var get:javax.servlet.http.Cookie = function (cookiename:string) {
return cookie.get(cookiename);
},
/**
* Convenience method to get a cookie value as a string.
*/
getString:string = function (cookiename:string) {
return cookie.get(cookiename).getValue();
},
/**
* Set a cookie value. Optional max age is in seconds.
* Must be called during at least a partial update.
*/
set = function (cookiename:string, value, maxagesecs:double) {
var xcon = facesContext.getExternalContext();
resp = xcon.getResponse(), cmap = xcon.getRequestCookieMap(), ck;
if (cmap.containsKey(cookiename)) {
ck = cmap.get(cookiename);
ck.setValue(value);
} else {
ck = new javax.servlet.http.Cookie(cookiename, value);
}
if (typeof maxagesecs !== 'undefined') {
ck.setMaxAge(maxagesecs);
}
resp.addCookie(ck);
};
return {'get': get, 'set': set, 'getString': getString};
}());
Note that for fetching cookie values in my get() method, I use the predefined cookie variable we’re handed by the XPages runtime, rather than fetching them raw via getHeader(). JSF has already parsed all the cookies out into individual objects, so it would be crazy not to take advantage of that.
The set() method is a bit more complicated, because if you already have a cookie set, you only want the method to change its value (and optionally its maximum age), rather than creating a whole new cookie and hence losing the other properties.
Finally, I added a getString() convenience method to cover the 99% of the time when you just want to fetch the cookie’s value and don’t care about any of the other properties of the Cookie object. As far as I can tell from the Chrome debugger, XPages sets the domain and path to sensible values by default. Oh, and as far as I can tell the above code works, but it’s a Friday and it has been pretty lightly tested, so no guarantees…
So, with this SSJS library loaded, you can give a control on a web page a default value from a cookie:
The length check I’m doing there is to make sure the value looks like a Notes/Domino short unique ID, as produced by @Unique. To set a value in an onChange event:
The 86400 being a day’s worth of seconds. Note that since the library is server-side JavaScript, you need to call it as part of an event that causes an HTTP connection, such as a partial refresh. If you want to set cookies without any HTTP round trip, you’ll need to use a completely different JavaScript API, the one provided by the browser.
Perhaps unfortunately, custom controls inherit the scope and variables of the XPages they are placed on. The upside of this is that you can bind data to document1 on an XPage, and then refer to document1 in custom controls on that XPage. The downside is that if you define a variable in an XPage (such as a data source), and then define it in the custom control as well, the two will clash. It appears that the custom control definition of the variable ends up overriding the XPage, but I wouldn’t rely on that behavior if I were you.
This means it’s probably a good idea to define data sources at the lowest possible level of the component tree, to limit their scope. You can define document data sources in a custom component, have no data sources at XPage level, and have the custom component load the document as expected by parsing the URL parameters.
So, what if you want to bind a document at XPage level, and then edit it at custom control level, without any risk of variable names clashing? That’s possible too, but is rather badly documented. There are some web pages discussing the technique, but they seem to be a bit out-of-date for Notes 8.5.3 and up. So, here’s the procedure:
Define your custom control. Don’t give it any data sources; no dominoDocuments.
Define a custom property. In the examples below, I’m calling it docToEdit.
In the property Type selector, use the folder button to bring up the expert options dialog, expand Data Sources, and select Domino Document. In the type field, it will show up as com.ibm.xsp.model.domino.DominoDocumentData.
In the Editor selector, select ‘Data Source Picker’.
In the controls which are part of the custom control, instead of using (say) document1.Size to bind to a field, use a JavaScript expression like #{compositeData.docToEdit.Size}.
Save and close the custom control, and drop it onto your XPage.
XPages will let you pick a document variable for the custom parameter using the GUI. However, if you try to build, you’ll get an error saying that the parameter can’t be primitive. So, you’ll need to edit the parameter to have a JavaScript value:
That’s it. Your control can now edit and save documents passed to it in the docToEdit parameter. Furthermore, the control will automatically know whether the document passed to it is in read mode or edit mode. Create mode also works, if you make sure that no document is loaded at XPage level (so nothing is passed to the custom control).
Close, but no banana. Your next thought might be to embed the view using an xp:dataTable, as that has more presentation options. However, xp:dataTable only has a single headerClass property which is applied to every TH element. If you try putting a comma-separated list of values in, which works with other styleClass properties, then it just puts the entire list into every th element’s style attribute, complete with commas.
All is not lost, however. While there’s only a single headerClass attribute, if you give it a value that changes every time—like #{javascript:@Random();} for example—you’ll discover that it is evaluated once for every table column.
So, we need a function which will iterate through our desired list of CSS classes, returning the next one in the list each time. Here’s some code:
var statefullyIterate = function (varname, values) {
var i = requestScope.get(varname);
if (i === null) {
i = 0;
} else {
i = i + 1;
}
requestScope.put(varname, i);
return values[i];
}
This function checks the requestScope to see if there’s a property variable with the name it expects. If so, it takes that value, increments it, stores it back in the requestScope, and uses the incremented value as the index into our list of CSS classes. If there’s no value, then the value’s 0 because we’ve never been called before, but we’ll store the 0 so it’ll be there next time we’re called.
Remember that the requestScope only lasts for the duration of an HTTP request, complete with page rendering, so we don’t need to bother resetting it. We just need to make sure we pick a suitable name for each place where we use the function.
Put the function in a Server Side JavaScript library, and import it as a resource. Now you can alter the xp:dataTable to start like this:
Of course, the fact that headerClass is evaluated multiple times is an undocumented feature, so you probably shouldn’t rely on this approach. Hopefully IBM will provide a way to individually style th elements in a future release.