Recent Content

Integrated tools #2
posted on 2016-10-15 23:53:14

In order to integrate any (interactive) application the following three parts need to be available, otherwise the integrator will have trouble one way or another:

  • objects, representing the domain model; these would be inspectable in order to get the contained information,
  • behaviours, allows the external user to invoke them,
  • notifications, to react to state changes

E.g. not only does an application need to expose its windows, but also it needs to allow to close or open a window and finally send updates if a window was closed or opened. Notifications in particular need to be in a channel that allows to poll multiple of them at the same time - if communication is done over a socket select and friends would allow the other side to control and react to multiple applications at the same time.

Debugging Java with ABCL
posted on 2016-09-10 00:05:24

So after adding a dispatch mechanism into the DISASSEMBLE function of ABCL I also want to show a neat way of disassembling arbitrary Java classes using one of the provided disassemblers.

First of, make sure that you have the ObjectWeb ASM library in your classpath (everything up from version 3 should work at least, perhaps even lower versions), note that in future releases you might be able to load it via Maven and one of the optional contribs as well, likely via (require '#:asm-all).

Next up, try (disassemble #'list) and confirm that some output is shown.

Now to show bytecode for arbitrary Java classes we've got to jump through some additional hoops - though perhaps at some point this could become a stable API as well:

(system::objectweb-disassemble (#"getResourceAsStream" (java:jclass "java.lang.Object") "/java/util/Random.class"))

I haven't tried this via the JAD disassembler, but it seems likely that a similar approach should work for it too.

Java integration woes
posted on 2016-08-18 21:26:13

Just a quick note on the JVM ecosystem since I've been wrestling with getting several different technologies to work together: It's a mess really.

The specific setup in this case is a mostly Java based project, sprinkled with some Kotlin code (which I only expect to grow in the future), using Maven as the build system. Added to that some Kotlin annotations (in lieu of using Kotlin in the first place).

Todays (and yesterdays) adventure was trying to get the Error Prone checker integrated with the existing system, which proved quite impossible, due to the fact that it's using a modified compiler(!) which conflicts with the use of Lombok annotation processing.

There are workarounds in the sense that Lombok can also be used to produce processed Java files (instead of byte code generation), however it seems like that process is less capable than the IDEA / internal processing and would have me remove a lot of val instances that didn't get their type inferred properly, making it an arduous process.

Summing this up, the fact that these tools integrate on different levels of the "stack", while also making tinkering with it relatively hard due to byte code generation, complicates this endeavour greatly. In the end I resolved to drop the Error Prone integration in favour of the much easier to setup SonarQube platform. I also hope that annotation processing for Lombok will improve such that we don't need workarounds in case of "invisible" getters anymore, for example.

Setting up an ABCL mirror from SVN to Git
posted on 2016-08-03 12:03:02

Copies of copies

As it so happens the ABCL main repository is held in Subversion, but since I'm more productive with Git I usually use a conversion to Git via the git-svn program. I've based my own copy off of slryus' one, however I had to fetch and update my own local copy since neither of us had done any fetching in quite some time. I'm writing down some notes below to make sure I (or others) can repeat the process in the future.

First we need a copy of an existing Git conversion.

git clone https://github.com/Ferada/abcl.git abcl-git
# or in case you have SSH access
git clone git@github.com:Ferada/abcl.git abcl-git

The master branch should be a direct mirror of the SVN repository, i.e. only have commits with git-svn annotations, like git-svn-id: http://abcl.org/svn/trunk/abcl@14851 1c010e3e-....

Next we want to initialise the SVN remote and fetch the new commits.

git svn init --prefix=abcl/ http://abcl.org/svn/trunk/abcl
git svn fetch -r 14791:14851

Note that the first revision in the fetch command is the last one in the Git master branch and the other one is the current HEAD of the SVN repository.

This process will take just a few moments, however while all the new commits will be based off of the master branch in Git, the first commit will be a duplicate and have more changes than the existing commit in Git.

2015-08-31 20:55 mevenson           │ │ o │ │ │ ansi-test: reference new git repository
2015-07-01 04:16 mevenson           o─┴─│─┴─┴─┘ abcl-asdf: fix usage with local repository   <<<<
2015-07-01 04:16 mevenson           │ I─┘ abcl-asdf: fix usage with local repository         <<<<
2015-06-30 18:42 mevenson           o abcl-asdf: correct metadata

The newly created first commit (14791 here) has lots of changes.

.dir-locals.el
CHANGES
COPYING
MANUAL
README
abcl.asd
abcl.bat.in
...

While the second, pre-existing one, has way less (and is just showing the same changes that are in the SVN commit).

contrib/abcl-asdf/abcl-asdf.asd
contrib/abcl-asdf/abcl-asdf.lisp
contrib/abcl-asdf/maven-embedder.lisp

To correct that and continue with a linear history I'm using the interactive rebase command.

git co -b test
git reset --hard abcl/git-svn
git rebase -i <commit _before_ the duplicated one>

Copy the hash of the correct, smaller commit and replace the pick ... line (at the top) that contains the duplicated commit with the one from the cloned-from Git repository, then exit the editor. Once the rebase is done we just need to update the ref for git-svn.

git update-ref refs/remotes/abcl/git-svn test

Note the syntax. If done correctly it will be updated in e.g. tig, if not there'll be a new entry showing up in git show-ref.

Lastly we want to rebase master to get the new commits.

git co master
git co -D test
git rebase abcl/git-svn master

Which will look somewhat like this:

2016-06-13 08:06 mevenson           o [master] {abcl/git-svn} {github/master} doc: note changes for abcl-1.3.4
2016-05-16 23:05 mevenson           o Update to asdf-3.1.7
2016-05-16 21:43 mevenson           o Update to jna-4.2.2

And push the updates.

git push origin master
Extension methods
posted on 2015-12-30 01:32:11

##

Let's assume for a moment that in our hypothetical Lisp machine environment we still had to run legacy applications (not entirely unlikely).

I just had the situation again that a Java application, IDEA IntelliJ, didn't render at all on dwm, my preferred window manager. The reason is unclear to me, except of course that every other UI toolkit manages to adhere to standards and renders fine. However there's a quick fix, using wmname to change the window manager name(?) to LG3D.

In our hypothetical environment I'd just extend the generic function idea-ultimate to handle this corner case with a :before method. In contrast to *nix shell aliases this would extend to all invocations of course simply by the fact that the application is only ever invoked by the above-mentioned function.

Gentoo, Lisp and Quicklisp
posted on 2015-11-27 19:33:43

Gentoo is so far

Containers as a failure of package management
posted on 2015-11-18 11:12:42
Setting up ABCL and LIRE
posted on 2015-11-11 20:34:29

Intro

The purpose of this article is to examine how using ABCL with existing libraries (arguably the main point of using ABCL at the moment) actually looks like in practice. Never mind integration with Spring, or other more involved frameworks, this will only touch a single library and won't require us to write from-Java-callable classes.

In the process of refining this I'm hoping to also get ideas about the requirements for building a better DSL for the Java FFI, based on the intended "look" of the code (that is, coding by wishful thinking).

Setup

Ensuring the correct package is somewhat optional:

(in-package #:cl-user)

Generally using JSS is a bit nicer than the plain Java FFI. After the contribs are loaded, JSS can be required and used:

(require '#:abcl-contrib)
(require '#:jss)

(use-package '#:jss)

Next, we need access to the right libraries. After building LIRE from source and executing the mvn dist command we end up with a JAR file for LIRE and several dependencies in the lib folder. All of them need to be on the classpath:

(progn
  (add-to-classpath "~/src/LIRE/dist/lire.jar")
  (mapc #'add-to-classpath (directory "~/src/LIRE/dist/lib/*.jar")))

Prelude

Since we're going to read pictures in a couple of places, a helper to load one from a pathname is a good start:

(defun read-image (pathname)
  (#"read" 'javax.imageio.ImageIO (new 'java.io.File (namestring pathname))))

To note here is the use of NEW from JSS with a symbol for the class name, the conversion of the pathname to a regular string, since the Java side doesn't expect a Lisp object and the #"" reader syntax from JSS to invoke the method read in a bit of a simpler way than using the FFI calls directly.

JSS will automatically "import" Java names, so the same function can simply be the following instead (provided that the names aren't ambiguous):

(defun read-image (pathname)
  (#"read" 'ImageIO (new 'File (namestring pathname))))

The names will be looked up again on every call though, so this option isn't the best performing one.

For comparison, the raw FFI would be a bit more verbose, but explicitely specifies all names:

(defun read-image (pathname)
  (jstatic "read" "javax.imageio.ImageIO" (jnew "java.io.File" (namestring pathname))))

Though with a combination of JSS and cached lookup it could be nicer, even though the setup is more verbose:

(defvar +image-io+ (jclass "javax.imageio.ImageIO"))
(defvar +file+ (jclass "java.io.File"))

(defun read-image (pathname)
  (#"read" +image-io+ (jnew +file+ (namestring pathname))))

At this point without other improvements (auto-coercion of pathnames, importing namespaces) it's about as factored as it will be (except moving every single call into its own Lisp wrapper function).

Building an index

To keep it simple building the index will be done from a list of pathnames in a single step while providing the path of the index as a separate parameter:

(defun build-index (index-name pathnames)
  (let ((global-document-builder
          (new 'GlobalDocumentBuilder (find-java-class 'CEDD)))
        (index-writer (#"createIndexWriter"
                       'LuceneUtils
                       index-name
                       +true+
                       (get-java-field 'LuceneUtils$AnalyzerType "WhitespaceAnalyzer"))))
    (unwind-protect
         (dolist (pathname pathnames)
           (let ((pathname (namestring pathname)))
             (format T "Indexing ~A ..." pathname)
             (let* ((image (read-image pathname))
                    (document (#"createDocument" global-document-builder image pathname)))
               (#"addDocument" index-writer document))
             (format T " done.~%")))
      (#"closeWriter" 'LuceneUtils index-writer))))

Note: This code won't work on current ABCL as is, because the lookup is disabled for for nested classes (those containing the dollar character). Because of this, the AnalyzerType class would have to be looked up as follows:

(jfield "net.semanticmetadata.lire.utils.LuceneUtils$AnalyzerType" "WhitespaceAnalyzer")

All in all nothing fancy, JSS takes care of a lot of typing as the names are all unique enough.

The process is simply creating the document builder and index writer, reading all the files one by one and adding them to the index. There's no error checking at the moment though.

To note here is that looking up the precise kind of a Java name is a bit of a hassle. Of course intuition goes a long way, but again, manually figuring out whether a name is a nested class or static/enum field is annoying enough since it involves either repeated calls to JAPROPOS, or reading more Java documentation.

Apart from that, this is mostly a direct transcription. Unfortunately written this way there's no point in creating a WITH-OPEN-* macro to automatically close the writer, however, looking at the LuceneUtils source this could be accomplished by directly calling close on the writer object instead - a corresponding macro might this then:

(defmacro with-open ((name value) &body body)
  `(let ((,name ,value))
     (unwind-protect
          (progn ,@body)
       (#"close" ,name))))

It would also be nice to have auto conversion using keywords for enum values instead of needing to look up the value manually.

Querying an index

The other way round, looking up related pictures by passing in an example, is done using an image searcher:

(defun query-index (index-name pathname)
  (let* ((image (read-image pathname))
         (index-reader (#"open" 'DirectoryReader
                                (#"open" 'FSDirectory
                                         (#"get" 'Paths index-name (jnew-array "java.lang.String" 0))))))
    (unwind-protect
         (let* ((image-searcher (new 'GenericFastImageSearcher 30 (find-java-class 'CEDD)))
                (hits (#"search" image-searcher image index-reader)))
           (dotimes (i (#"length" hits))
             (let ((found-pathname (#"getValues" (#"document" index-reader (#"documentID" hits i))
                                                 (get-java-field 'builders.DocumentBuilder "FIELD_NAME_IDENTIFIER"))))
               (format T "~F: ~A~%" (#"score" hits i) found-pathname))))
      (#"closeReader" 'LuceneUtils index-reader))))

To note here is that the get call on java.nio.file.Paths took way more time to figure out than should've been necessary: Essentially the method is using a variable number of arguments, but the FFI doesn't help in any way, so the array (of the correct type!) needs to be set up manually, especially if the number of variable arguments is zero. This is not obvious at first and also takes unnecessary writing.

The rest of the code is straightforward again. At least a common wrapper for the length call would be nice, but since the result object doesn't actually implement a collection interface, the point about having better collection iteration is kind of moot here.

A better DSL

Considering how verbose the previous examples were, how would the "ideal" way look like?

There are different ways which are more, or less intertwined with Java semantics. On the one end, we could imagine something akin to "Java in Lisp":

(defun read-image (pathname)
  (ImageIO/read (FileInputStream. pathname)))

Which is almost how it would look like in Clojure. However, this is complicating semantics. While importing would be an extension to the package mechanism (or possibly just a file-wide setting), the Class/field syntax and Class. syntax are non-trivial reader extensions, not from the actual implementation point of view, but from the user point of view. They'd basically disallow a wide range of formerly legal Lisp names.

(defun read-image (pathname)
  (#"read" 'ImageIO (new 'FileInputStream pathname)))

This way is the middle ground that we have now. The one addition here could be that name lookup is done at macro expansion / compilation time, so they are fixed one step before execution, whereas at the moment the JSS reader macro will allow for very late bound name lookup instead.

The similarity with CLOS would be the use of symbols for class names, but the distinction is still there, since there's not much in terms of integrating CLOS and Java OO yet (which might not be desirable anyway?).

Auto-coercion to Java data types also takes place in both cases. Generally this would be appropriate, except for places where we'd really want the Java side to receive a Lisp object. Having a special variable to disable conversion might be enough for these purposes.

If we were to forego the nice properties of JSS by requiring a function form, the following would be another option:

(defun read-image (pathname)
  $(read 'ImageIO (new 'FileInputStream pathname)))

Where $(...) would be special syntax indicating a Java method call. Of course the exact syntax is not very relevant, more importantly static properties could be used to generate a faster, early bound call by examining the supplied arguments as a limited form of type inference.

Summary

After introducing the necessary steps to start using ABCL with "native" Java libraries, we transcribed two example programs from the library homepage.

Part of this process was to examine how the interaction between the Common Lisp and Java parts looks like, using the "raw" and the simplified JSS API. In all cases the FFI is clunkier than needs be. Especially the additional Java namespaces are making things longer than necessary. The obvious way of "importing" classes by storing a reference in a Lisp variable is viable, but again isn't automated.

Based on the verbose nature of the Java calls an idea about how a more concise FFI DSL could look like was developed next and discussed. At a future point in time this idea could now be developed fully and integrated (as a contrib) into ABCL.

Public Service Public Key Setup
posted on 2015-10-05 14:05:12

Each organisational unit gets one defined key space, which is designated in the issued keys via a natural language identifier.

For this document, let's use the Ministry of Funny Walks (MFW) and the Ministry of Silly Hats (MSH) as examples of organisational units.

Each organisational unit uses public keys to sign their documents. Keys are compartmentalised by year (or possibly smaller time frames) and possible subsections of the top organisational unit.

Citizens create their own key and register it with the MFW and other units. Registering means that the MFW will verify the identity of the requester (via ID card) and then sign the requesters key with current signing key of the MFW.

Communication between citizens and the MFW will be done against the current public keys of citizens and the MFW. Emails and other documents will be signed by individual employees of the MFW as appropriate, or with special multi-user keys in order to protect the identities of employees; there might be a case of signing with employee keys but not distributing their public keys to the general public in order to maintain a notion of identity. That said, this bears the risk of accidental disclosure at a later point, meaning that it doesn't provide perfect forward secrecy.

Citizens may verify public key hashes via web sites, newspapers and publicly displayed information in government offices.

Limits of Unix shell
posted on 2015-08-20 14:54:10

Let's go back to the GNU Coreutils list of tools. ls for example. Usually the user will have set some alias to ls instead of the plain invocation, either to enable highlighting (--color), sorting (--sort), or to add more information than just the filenames (e.g. --format). There is even integration with Emacs (--dired).

The question then is: How much of the functionality of ls is actually devoted to secondary formatting instead of listing files? And shouldn't this functionality be moved into separate tools? Since output is intended for multiple kinds of recipients, additional data creeps in and complicate tools a lot.

Alternatively, we could imagine using ls only to get unformatted and unsorted output. Which would then be passed through to a sort command and a fmt command of sorts. Of course this all takes some more time, re-parsing of output etc., so it's understandable in the interest of performance not to do this in the traditional Unix shell.

However, let's assume a more sophisticated shell. Assuming ls is limited to listing files, then the user will alias ls to a pipeline instead, namely something akin to ls | sort | fmt. Then again, formatting is part of the user interface, not the functionality, so it should rather be part of the internal shell formatting, possibly exposed as separate filters as well.

The result of ls is a (possibly nested) directory listing. Regardless of post-processing, this "object" should still be available for further investigation. Which means that while sorting may be applied destructively, formatting may not, unless specifically requested, in which case the result would be a kind of "formatted" object (text, GUI widget) instead.

In other terms, the user should be able to refer to the last results immediately, instead of rerunning the whole pipeline. E.g. coming from Common Lisp, variables like * to *** will store the last three results for interactive use. In the shell then, ls would set * to the generated directory listing; since the listing is also most likely printed to the screen, the full listing will also be stored (in that object) to be used again if e.g. * is requested again. Rerunning the command, on the other hand, will possibly generate a different directory listing as files may have been changed, so there is an immediate difference between the two forms.

Examples

The pipeline ls | wc -l is (at least for me) often used to get the number of files in the (current) directory. Unfortunately there is no direct way to get this number directly except to enumerate the entries in a directory (under Linux that is).

Previous Next

This blog covers emacs, git, hardware, java, kotlin, lisp, postgresql, tachikoma, unix, work

View content from 2018-04, 2017-12, 2017-07, 2017-06, 2016-11, 2016-10, 2016-09, 2016-08, 2015-12, 2015-11, 2015-10, 2015-08, 2015-06, 2015-04, 2015-02, 2015-01, 2014-12, 2014-11, 2014-08


Unless otherwise credited all material Creative Commons License by Olof-Joachim Frahm