BeanShell Debugger

vorhergehende Artikel in: Java Komponenten
12.08.2016

In einem Kundenprojekt, das wir zur Zeit im Rahmen des Jobs bearbeiten, existiert ein Legacy-Framework, das aus den üblichen Gründen nicht abgeschafft werden kann. Dieses Framework setzt kräftig auf BeanShell. Das brachte mich dazu, eine Debug-Funktionalität für BeanShell-Skripte zu schaffen.

Der Autor des Frameworks hat es geschafft, aus einer streng typisierten Sprache (Java) eine typlose Sprache zu bauen, in der man nach jedem Methodenaufruf erstmal rauskriegen muss, was für einen Typ der Rückgabewert denn nun hat.

Die Anwendung wird über eine Java-GUI parametriert - die Parameter werden in einer relationalen Datenbank gehalten.

Es existieren diverse Stellen, wo simple Parametrierung nicht reicht - statt dessen müssen dort Codefragmente gebaut werden, die als scripted Java mittels Beanshell ausgeführt werden. Die dazu zur Verfügung stehende Editorkomponente hat noch nicht einmal grundlegende Fähigkeiten, wie etwa Syntax Highlighting eingebaut, was das Editieren und die Fehlersuche extrem erschwert: Bisher erschöpfte sich das Hilfsmittel im Einfügen von Debugausgaben im Script.

Nachdem meine Leidensschwelle überschritten war, überlegte ich mir, dass ich gerne in der Lage wäre, ein BeanShell-Skript zu debuggen. Die genauen Anforderungen waren:

  • Es muss möglich sein, Breakpoints zu setzen
  • Hält das Skript an einem Breakpoint, will ich alle Variablen sehen
  • Beanshell-Debugging muss während der Laufzeit der Anwendung an- und ausgeschaltet werden können - am besten ohne die Anwendung selbst neu starten zu müssen
  • Der Debugger fängt alle Exceptions, die während der Ausführung des Skripts von diesem selbst nicht abgefangen werden und hält automatisch die Ausführung an, sofern das Debugging aktiv ist.
  • Der Debugger der IDE wird verwendet.

Gelöst habe ich diese Anforderungen mit einer Klasse, die unten angehängt ist. Sie ist einfach zu integrieren: An allen Stellen, an denen sonst steht:

bsh.Interpreter inter=new bsh.Interpreter();
inter.eval("some code");

muss man eine Änderung wie folgt vornehmen:

bsh.Interpreter inter=new bsh.Interpreter();
de.elbosso.util.BeanShellDebugger.eval(inter,"some code");

Der BeanShellDebugger umgibt das übergebene Skript-Fragment mit Code zur Instrumentierung. Das Anhalten an Breakpoints wird realisiert, indem im Skript undefinierte Funktionen aufgerufen werden - Beanshell erlaubt es nämlich, nicht definierte Funktionsaufrufe abzufangen und darauf zu reagieren. Der BeanShellDebugger tut genau dies: Wann immer eine undefinierte Methode aufgerufen wird, ruft er seinerseits eine seiner eigenen Methoden auf und übergibt dieser den Namen der Methode, eventuell übergebene Aufrufparameter und den aktuellen Callstack. Über diesen kann man auf alle Skriptvariablen zugreifen und diese im Debugger der IDE analysieren.

Hier ein Beispiel-Skript um zu zeigen, wie es funktionieren kann:

//Switch, to enable (true) or disable (false) Debugging
___eb_debug_on___=true;
doFunc()
{
	a=3+4;
//Next line causes Breakpoint - Callstack allows accessing Variables a and c
	hallo();
	b=a*2;
//Next line causes Breakpoint - Callstack allows accessing Variables a, b, and c
	huhu(b);
	System.out.println(this.variables);
}
c=5;
doFunc();
System.out.println("huhu");
c=null;
//Next line causes NullPointerException - because the Script does not handle it, it causes
a Breakpoint - Callstack allows accessing Variables exp and c - exp being the Exception being raised
print(c.toString());

Lizenz
BeanShellDebugger.java

Artikel, die hierher verlinken

BeanShell Debugger - neue Version

19.10.2019

Ich habe den hier bereits vorgestellten BeanShellDebugger nochmals überarbeitet...

BeanShell Debugger ohne IDE

24.09.2016

Der vor einiger Zeit vorgestellte BeanShellDebugger funktioniert nur dann gut, wenn die Anwendung noch entwickelt wird und man noch Zugriff auf den Debugger der IDE hat.

Alle Artikel rss Wochenübersicht Monatsübersicht Codeberg Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Multi-User-WebDAV, Docker, GitHub

    17.11.2019

    Nachdem ich mich in letzter Zeit verstärkt mit Docker und dem zugehörigen Ökosystem beschäftige, habe ich begonnen, verschiedenste Dienste in Containern zu testen um zu sehen, ob in manchen Fällen LXC oder KVM nicht doch die bessere Wahl wäre...

    Weiterlesen...

Neueste Artikel

  • Migration der Webseite und aller OpenSource Projekte

    In eigener Sache...

    Weiterlesen...
  • AutoHideToolbar für Java Swing

    Ich habe eine neue Java Swing Komponente erstellt: Es handelt sich um einen Wrapper für von JToolBar abgeleitete Klassen, die die Werkzeugleiste minimieren und sie nur dann einblenden, wenn der Mauszeiger über ihnen schwebt.

    Weiterlesen...
  • Integration von EBMap4D in die sQLshell

    Ich habe bereits in einem früheren Artikel über meine ersten Erfolge berichtet, der sQLshell auf Basis des bestehenden Codes aus dem Projekt EBMap4D eine bessere Integration für Geo-Daten zu spendieren und entsprechende Abfragen, bzw. deren Ergebnisse auf einer Kartenansicht zu visualisieren.

    Weiterlesen...

Manche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.

Wer daran teilhaben und eventuell sogar davon profitieren möchte, muss damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.

Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...

PS: Meine öffentlichen Codeberg-Repositories findet man hier.