<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Under the (Content-)Hood &#187; Debugger</title>
	<atom:link href="http://axel-faust.de/?cat=18&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://axel-faust.de</link>
	<description>Alfresco et al in depth</description>
	<lastBuildDate>Mon, 15 Jul 2013 22:08:21 +0000</lastBuildDate>
	<language>de-DE</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.0.38</generator>
	<item>
		<title>Debugging Alfresco #1 &#8211; Eclipse JavaScript Debugger und Alfresco Repository</title>
		<link>http://axel-faust.de/?p=47&#038;lang=de</link>
		<comments>http://axel-faust.de/?p=47&#038;lang=de#comments</comments>
		<pubDate>Fri, 03 Feb 2012 23:32:04 +0000</pubDate>
		<dc:creator><![CDATA[afaust]]></dc:creator>
				<category><![CDATA[Alfresco]]></category>
		<category><![CDATA[Debugger]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Entwicklung]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Rhino Script Engine]]></category>
		<category><![CDATA[Mozilla Rhino]]></category>

		<guid isPermaLink="false">http://axel-faust.de/?p=47&#038;lang=de</guid>
		<description><![CDATA[Das Debuggen von Alfresco ist nicht immer ein einfaches Spiel. Die Java Bestandteile können mit den jeweiligen Remote Debugger der gängigen IDEs im laufenden System untersucht werden. Bei JavaScript und FreeMarker Templates stellt sich die Sache schon etwas komplizierter dar. &#8230;<p class="read-more"><a href="http://axel-faust.de/?p=47&#038;lang=de">Weiterlesen &#187;</a></p>]]></description>
				<content:encoded><![CDATA[<p>Das Debuggen von Alfresco ist nicht immer ein einfaches Spiel. Die Java Bestandteile können mit den jeweiligen Remote Debugger der gängigen IDEs im laufenden System untersucht werden. Bei JavaScript und FreeMarker Templates stellt sich die Sache schon etwas komplizierter dar.</p>
<p>Während die in Alfresco verbaute Rhino Engine mit einem eigenen, embedded Debugger daher kommt, gibt es für FreeMarker aktuell &#8211; zumindest meines Wissens &#8211; kein Tooling. Aber auch der embedded Rhino Debugger ist alles andere als handlich. Zum Einen stellt er für Entwickler einen Bruch in einer schon umfangreichen Ansammlung von Tools dar und zum Anderen kann er nur auf Servern mit graphischer Oberfläche eingesetzt werden &#8211; ein Debugging einer Entwicklungs- / Testumgebung auf einem Blech oder einer einfachen Server VM ist somit nicht möglich. Ich habe mir daher zuletzt etwas Zeit genommen, die neuen JavaScript Debugger Features des <a title="JavaScript Development Tools (JSDT)" href="http://www.eclipse.org/webtools/jsdt/">Eclipse JavaScript Development Tools (JSDT)</a> Projekts auszuprobieren.</p>
<p>Seit Version 3.7 der Eclipse IDE sind die notwendigen Bestandteile des JSDT in jeder Distribution enthalten, die das Web Standard Tools Sub-Projekt mitliefert. Nach anfänglichen Problemen aufgrund der noch jungen Debugger Komponente bin ich bei meinen Tests schnell beim aktuellen Milestone 4 des Juno Releases gelandet. Das Wiki des Projekts enthält eine recht nützliche Anleitung zur Verwendung des <a title="JSDT Rhino Integration" href="http://wiki.eclipse.org/JSDT/Debug/Rhino">Rhino Debugger Supports</a> als auch zu unserem speziellen Anwendungsfall der <a title="JSDT Rhino Embedded Integration" href="http://wiki.eclipse.org/JSDT/Debug/Rhino/Embedding_Rhino_Debugger">Integration in eine embedded Rhino Engine</a>. Ein kleines <a title="JSDT Debug FAQ" href="http://wiki.eclipse.org/JSDT/Debug/FAQ">FAQ</a> zu den häufigsten Problemen gibt es natürlich ebenfalls.</p>
<p>Damit man mit Eclipse remote den JavaScript Code von Web Scripten und Co debuggen kann, muss im Alfresco Server eine entsprechende Debugger-Komponente laufen und über eine TCP Schnittstelle angesprochen werden können (vgl. der <a title="Java Platform Debugger Architecture" href="http://java.sun.com/javase/technologies/core/toolsapis/jpda/">Java Platform Debugger Architecture</a>). Die notwendigen JARs liefert das JSDT gleich als Teil seiner Plugins mit, sodass diese &#8220;nur noch&#8221; in das &lt;tomcat&gt;/webapps/alfresco/WEB-INF/lib Verzeichnis kopiert werden müssen (wegen einer Class-Abhängigkeit auf die Rhino Engine ist &lt;tomcat&gt;/shared/lib nicht möglich). Die notwendigen Bibliotheken sind:</p>
<ul>
<li>org.eclipse.wst.jsdt.debug.rhino.debugger_&lt;version&gt;.jar</li>
<li>org.eclipse.wst.jsdt.debug.transport_&lt;version&gt;.jar</li>
</ul>
<p>Entsprechend der Anleitung zum Embedden müssen wir den Debugger an den Rhino Context binden und aktivieren. Dazu reicht es, eine kleine Bean zu implementieren und durch Spring beim Bootstrap der Alfresco Webapplikation ausführen zu lassen.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.prodyna.debug.rhino</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.text.MessageFormat</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.eclipse.wst.jsdt.debug.rhino.debugger.RhinoDebugger</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.mozilla.javascript.ContextFactory</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.beans.factory.InitializingBean</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> RemoteJSDebugInitiator <span style="color: #000000; font-weight: bold;">implements</span> InitializingBean <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> DEFAULT_PORT <span style="color: #339933;">=</span> <span style="color: #cc66cc;">9000</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> DEFAULT_TRANSPORT <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;socket&quot;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">boolean</span> suspend <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// suspend until debugger attaches itself</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">boolean</span> trace <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// trace-log the debug agent</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> port <span style="color: #339933;">=</span> DEFAULT_PORT<span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> transport <span style="color: #339933;">=</span> DEFAULT_TRANSPORT<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// the global context factory used by Alfresco</span>
	<span style="color: #000000; font-weight: bold;">private</span> ContextFactory contextFactory <span style="color: #339933;">=</span> ContextFactory.<span style="color: #006633;">getGlobal</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> afterPropertiesSet<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// setup debugger based on configuration</span>
		<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> configString <span style="color: #339933;">=</span> <span style="color: #003399;">MessageFormat</span>.<span style="color: #006633;">format</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">&quot;transport={0},suspend={1},address={2},trace={3}&quot;</span>,
			<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">transport</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">suspend</span> <span style="color: #339933;">?</span> <span style="color: #0000ff;">&quot;y&quot;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;n&quot;</span>,
				<span style="color: #003399;">String</span>.<span style="color: #006633;">valueOf</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">port</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">trace</span> <span style="color: #339933;">?</span> <span style="color: #0000ff;">&quot;y&quot;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;n&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">final</span> RhinoDebugger debugger <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RhinoDebugger<span style="color: #009900;">&#40;</span>configString<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">contextFactory</span>.<span style="color: #006633;">addListener</span><span style="color: #009900;">&#40;</span>debugger<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		debugger.<span style="color: #006633;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setSuspend<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">boolean</span> suspend<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">suspend</span> <span style="color: #339933;">=</span> suspend<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setTrace<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">boolean</span> trace<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">trace</span> <span style="color: #339933;">=</span> trace<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setPort<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> port<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">port</span> <span style="color: #339933;">=</span> port<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setTransport<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> transport<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">transport</span> <span style="color: #339933;">=</span> transport<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setContextFactory<span style="color: #009900;">&#40;</span>ContextFactory contextFactory<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">contextFactory</span> <span style="color: #339933;">=</span> contextFactory<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Diese Bean kann dann durch folgende Beandeklaration in der &lt;tomcat&gt;/shared/classes/alfresco/extension/dev-context.xml aktiviert werden.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bean</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;pd.jsRemoveDebugger&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;com.prodyna.debug.rhino.RemoteJSDebugInitiator&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;port&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>8000<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/value<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;trace&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>true<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/value<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/bean<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>Nach dem Neustart des Alfresco Repository Servers kann man sich mit Eclipse via Remote JavaScript Debugging auf die Rhino Engine aufschalten. Hierzu muss lediglich die entsprechende Debug Configuration angelegt werden, bei der die verwendeten Parameter der Serverkomponente einzutragen sind.</p>
<p><a href="http://axel-faust.de/wp/wp-content/uploads/2012/01/Rhino-Debug-Configuration.png"><img class="alignnone size-full wp-image-53" title="Eclipse JavaScript Debugger - Rhino Connector Konfiguration" src="http://axel-faust.de/wp/wp-content/uploads/2012/01/Rhino-Debug-Configuration.png" alt="" width="1014" height="640" /></a></p>
<p>Leider ist damit noch nicht alles getan, um erfolgreich serverseitiges JavaScript aus Eclipse heraus debuggen zu können. Ähnlich wie der Classpath müssen Skripte im Eclipse in einer bestimmten Struktur liegen, damit sie mit den auf den Server ausgeführten Skripten abgeglichen werden können. Nur wenn dieser Abgleich erfolgt ist, werden Breakpoints, die in JavaScript Dateien ähnlich wie in Java mit einem Doppelklick auf den sog. Ruler eingestellt werden, von Eclipse an den Server übermittelt und aktiviert.</p>
<p>Die notwendige Source Code Struktur für remote debuggte Skripte richtet sich nach dem bei der Übergabe an die Rhino Engine angegebenen Source Namen. Alfresco verwendet hier durchgehen die File URI des Hauptskripts, d.h. also für einen Repository Server, welcher in &#8220;D:\Applications\Swift\tomcat&#8221; deployed wurde, beträgt die URI für den Web Script Controller sites.get.js &#8220;file://D:/Applications/Swift/tomcat/webapps/alfresco/WEB-INF/classes/alfresco/templates/webscripts/org/alfresco/repository/sites/sites.get.js&#8221;. Laut dem FAQ des JSDT wird eine solche URI ohne den &#8220;file://D:/&#8221; Prefix auf ein automatisch angelegtes Source Projekt &#8220;External JavaScript Source&#8221; gemapped. Dies traf bei mir nicht zu und nach Studium des Source Code des JSDT Plugins habe ich eine funktionierende Alternative gefunden: das erste Pfadelement entspricht einem Source Projekt und der Rest des Pfades ist relativ zu diesem zu betrachten. Um also JavaScript Web Script <a href="http://axel-faust.de/wp/wp-content/uploads/2012/02/JS-Debug-Source-Project.png"><img class="size-medium wp-image-59 alignleft" title="Source Projekt - Struktur" src="http://axel-faust.de/wp/wp-content/uploads/2012/02/JS-Debug-Source-Project-300x149.png" alt="" width="300" height="149" /></a>Controller in meinem Swift Repository debuggen zu können, musste ich dessen Web Scripte in einem Projekt namens &#8220;Applications&#8221; in einer Ordnerstruktur &#8220;Swift/t/tomcat/webapps/alfresco/WEB-INF/classes/alfresco/templates/webscripts/&#8221; zur Verfügung stellen. Am einfachsten geht dies, indem man den Source Code des Alfresco Remote API Projekts als Source in eine solche Struktur linkt.</p>
<p><a href="http://axel-faust.de/wp/wp-content/uploads/2012/02/JS-Debug-Source-Project-Linking.png"><img class="alignnone size-full wp-image-61" title="Source Projekt - Externe Sourcen Linken" src="http://axel-faust.de/wp/wp-content/uploads/2012/02/JS-Debug-Source-Project-Linking.png" alt="" width="1148" height="548" /></a></p>
<p>Nachdem diese letzte Konfiguration abgeschlossen wurde, werden Breakpoints, die in Alfresco Web Script, wie z.B. sites.get.js gesetzt wurden, sauber an den Server übertragen. Bei der nächsten Ausführung einer Site Suche in Alfresco Share hält der Debugger dann entsprechend an der definierten Position an und lässt das Web Script mit den gewohnten Funktionen wie Step Over / Into, der Variables sowie Expressions View untersuchen. Besonders letztere ist aktuell noch übermäßig wertvoll, da der Debugger mit Java Objekten als Variablenwerte in der Variables View nicht viel anfangen kann.</p>
<p><a href="http://axel-faust.de/wp/wp-content/uploads/2012/02/debug_sites_get.png"><img class="alignnone size-full wp-image-62" title="Eclipse JavaScript Debugger - Variables" src="http://axel-faust.de/wp/wp-content/uploads/2012/02/debug_sites_get.png" alt="" width="1300" height="768" /></a></p>
<p><a href="http://axel-faust.de/wp/wp-content/uploads/2012/02/debug_sites_get_expressions.png"><img class="alignnone size-full wp-image-66" title="Eclipse JavaScript Debugger - Expressions" src="http://axel-faust.de/wp/wp-content/uploads/2012/02/debug_sites_get_expressions.png" alt="" /></a></p>
<p><em><strong>Zwischenfazit: </strong></em>Mit dem Eclipse JSDT lassen sich JavaScript Dateien, die Teil der Alfresco Applikation &#8211; d.h. dessen Classpath &#8211; sind, aus der gewohnten Entwicklungsumgebung heraus remote debuggen. Damit entfällt die bisherige Einschränkung des Rhino Debuggers, dass JavaScript Dateien nur auf lokalen Servern bzw. Servern mit graphischer Oberfläche debug-bar sind. Die Einrichtung des JSDT Remote Debuggers mag etwas gewöhnungsbedürftig sein, ist jedoch mit den zur Verfügung stehenden Mitteln des Source Linkings  schnell und ohne unnötige Code Redundanz im Workspace realisierbar. Aktuell gibt es aufgrund des noch jungen Debuggers und der Art und Weise, wie Alfresco die Rhino Engine integriert hat, ein paar Besonderheiten und Einschränkungen in der Nutzung des Debuggers. Auf diese werden ich in kommenden Posts dieser Serie eingehen und &#8211; soweit möglich &#8211; Lösungen vorstellen.</p>
]]></content:encoded>
			<wfw:commentRss>http://axel-faust.de/?feed=rss2&#038;p=47</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
