Archive for the ‘Tech’ Category

Shortly after the release of Tawny-OWL 1.5.0 (http://www.russet.org.uk/blog/3110), I noticed a strange message being printed to screen, which looks like this:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further
details.

What strangeness is this? I had never heard of SLF4J before, and could not see why this was happening; so I googled around, and found out. The reason is that I had switched versions of the OWL API (http://dl.acm.org/citation.cfm?id=2019471), and this now uses the SLF4J API as a logging API. By default, it prints out this error message.

Slightly irritated by this, I tweeted

#slf4j I mean, who decided to print a message to tell me I am using a no-op logger. How is that no-op?

To which the author of SLF4J Ceki Gülcü kindly replied:

@phillord if you place slf4j-nop.jar on the class path the nop message should not appear.

But this seems unsatisfying to me. The reason for the message is that SLF4J is a facade, and needs a logging backend. It prints this error message when it cannot find one. The way to switch it off is to include the slf4j-nop dependency (which, ironically, does not contain the NOP logger — that’s in slf4j-api).

Normally, I would say that a library should not print to stderr in normal operation. But I can appreciate SLF4J logic here; it has to do something by default. For most libraries, my response would be “use a proper logger then!”, but, of course, SLF4J does not have that option — it cannot do this during bootstrap, and it either prints to stderr or just dumps all logs.

Okay, no worries, just include slf4j-nop in your project? Unfortunately, SLF4J say explicitly not to do this.

If you are packaging an application and you do not care about logging, then placing slf4j-nop.jar on the class path of your application will get rid of this warning message. Note that embedded components such as libraries or frameworks should not declare a dependency on any SLF4J binding but only depend on slf4j-api

Now, for a library/application/textual UI like Tawny-OWL (1303.0213), the distinction between “library” and “end-user” is not that clear, so this advice is not that useful. SLF4J justify this by saying:

When a library declares a compile-time dependency on a SLF4J binding, it imposes that binding on the end-user, thus negating SLF4J’s purpose.

Of course, imposing a binding of the end-user is a negative thing, but then is not forcing users to choose a binding also an imposition? It is made worse in my case, because I also get this message from ELK, another dependency of Tawny-OWL:

log4j:WARN No appenders could be found for logger
(org.semanticweb.elk.config.ConfigurationFactory).
log4j:WARN Please initialize the log4j system properly.

A similar error message for a similar reason. I now have to explicitly pacify the logging from two libraries in my project!

The curious thing about the whole situation is that everyone is behaving entirely reasonably. I can fully appreciate the logic of SLF4J, I can fully understand why the OWL API uses it, and I hope that others appreciate why I do not want print outs to stderr. It’s another one of those situations which show that software is difficult, and that often there are only compromises; whether something is a solution or a problem depends on where you sit.

For what it is worth, my own advice is that libraries and framework developers should always include the slf4j-nop if they use slf4j-api. If their end-users want logging, they can always use dependency exclusions to enable it.

I’d like to thank the members of the SLF4J users list, and Ceki for their helpful and polite responses to my questions. You can read the full thread on gmane. This article was, however, written without their endorsement.

  • Update

I have written a followup to this article.

Bibliography

I am pleased to annouce the 1.5.0 release of Tawny-OWL, the fully programmatic ontology construction environment.

As with the 1.4.0 release, there has been quite a long gap between releases. The main change for this release has been the move to the OWL API version 4.

The next release of Tawny will include more extensions to the patterns.

Tawny 1.5.0 is now available on Clojars.

I am pleased to announce this 1.4.0 release of Tawny-OWL. It is with some surprise that I find that it is about 8 months since the last release, which is indicative of the relatively stable state of Tawny.

The main addition to this release has been further support for patterns, which now include what I am calling “facets”, as well as some general functions for grouping the entities created using a pattern with annotations. I have had a lot of discussion about the implementation of this feature and that it should be useful in practice.

The main motivation behind making this release now is the development of a Tawny Tutorial for ICBO 2015. The features are stable for the release are stable, so the release has not been rushed out the door, but I wanted to use them in the tutorial as they really simplify some aspects.

Tawny-OWL 1.4.0 is now available on Clojars.

While I have been working on a manual called Take Wing for Tawny-OWL (http://www.russet.org.uk/blog/3030) for some time, it is far from finished. In the meantime, I am giving a tutorial at this years ICBO, and the slides for this are now relatively advanced, although I have a few more sections and some checking to do. The full tutorial is available (http://github.com/phillord/tawny-tutorial), and I think it offers are fairly comprehensive guide to basic Tawny-OWL usage.

I am fairly pleased with the tutorial as it stands. It is written up as a semantic document using my lentic package (http://www.russet.org.uk/blog/3047) which seems to be working well (although I discovered a few bugs with the asciidoc support in the course of writing the tutorial!).

For anyone who is thinking of coming, the pre-requisities for the tutorial are now online. I am planning to do a large part of the tutorial in a “follow-my-leader” fashion; it’s always difficult to predict the state of the networks at these events, so it would help significantly if at least some of the people coming could work through this short document before hand.

Bibliography

Lentic is a package which implements lenticular text — two Emacs buffers that contain the same content, but are otherwise independent. Unlike indirect-buffers, which must contain absolutely identical strings, lentic buffers can contain different text, with a transformation between the two.

It was not my original plan to have another release so soon after the last release (http://www.russet.org.uk/blog/3068). However, the work that I had planned for that release turned out to be very-straightforward.

For this release, introduces a new form of buffer which is an unmatched block buffer. The details do not matter — the practical upshot is that with, for example, org-mode it is now possible to have more than one style of source block. In my examples directory, I have an org-mode file with “hello world” in three different languages (Clojure, Python and Emacs-Lisp). When lentic, you get four views, each in a different mode, and syntactically correct. Not a use I think I would suggest, but a nice demonstration.

Lentic is now available on MELPA, MELPA stable and github.

Bibliography

Lentic is a package which implements lenticular text — two Emacs buffers that contain the same content, but are otherwise independent. Unlike indirect-buffers, which must contain absolutely identical strings, lentic buffers can contain different text, with a transformation between the two.

This has several uses. Firstly, it allows a form of multi-modal editing, where each lentic buffer shows the text in a different mode. For example, this can be used to edit literate Haskell code. This should work with indirect-buffers, but in practice does not because the buffers share text-properties. These are a feature of the buffer strings in Emacs, and are used by some modes for their functionality; when two modes work on the same string, each tends to reset the text properties of the other.

It is possible to take this form of multi-modal editing further, where the different buffers contain different syntax. So, for example, one buffer might be in fully valid Emacs-Lisp, while the other might be a fully-valid org-mode buffer. This allows a literate programming technique even without specific support for this form of programming in the language. Taken to the extreme, it is even possible for the buffers to contain completely different strings; I have not found a good practical use for the extreme yet, but lentic now supports a rot-13 transformation which demonstrates its capabilities.

Lentic can also be used to create persistant views of the same text. For example, lentic could be used to maintain a view of the imports of a java file, or the namespace form in clojure, or the preamble of a latex document. Unlike a second window, this view persists even if it is not visible. Alternatively, one view could use very small text, and the other could contain larger text, allowing rapid navigation.

Lentic 0.8 contains a number of new features since the 0.7 [release] (http://www.russet.org.uk/blog/3047). The biggest change is that it is possible to produce any number of lentic buffers, rather than just two as previously. This means that its multi-modal and persistant view capabilities can be used at the same time.

Lentic is now available on MELPA, MELPA stable and github.

Bibliography