Debuggen in Oracle Application Express
April 2009 - Als ontwikkelaar word je niet graag geconfronteerd met bugs. Feit is alleen dat bijna alle applicaties bugs bevatten en het is dus voor een ontwikkelaar erg belangrijk om de juiste middelen te hebben om deze bugs op te sporen en uiteindelijk te verhelpen. De meeste Oracle ontwikkelaars zullen bekend zijn met debuggen in Oracle Forms applicaties of debuggen van packages door middel van een tool als SQL Developer of TOAD. Maar hoe debug je een web applicatie gemaakt in Oracle Application Express? In dit Whitebook worden de belangrijkste debug mogelijkheden besproken die de Oracle APEX ontwikkelaar voorhanden heeft.
Debug optie
De eenvoudigste manier om een APEX applicatie te debuggen, is door middel van het starten van de applicatie in debug modus. Er zijn twee manieren om dit te doen. De eerste manier is door op de debug link in de Developer toolbar te klikken, deze toolbar is beschikbaar als de applicatie wordt gestart vanuit de Application Builder.
Figuur 1, De APEX toolbar
De tweede manier om de applicatie in debug modus te starten, is door de URL van de applicatie aan te passen. De applicatie wordt in debug modus gestart wanneer de vijfde parameter in de APEX URL de waarde YES heeft.
f?p=100:1:&APP_SESSION.::YES
In een productie omgeving waarbij er geen toegang is tot de Application Builder, is de URL de enige manier om debug modus te activeren. Debuggen is echter niet mogelijk wanneer een applicatie "Run Only" is geinstalleerd. Ook kan het debuggen per applicatie worden uitgeschakeld in de applicatie definitie, in dat geval is het uberhaupt niet mogelijk om debug modus te starten voor de applicatie.
Zodra de debug modus is geactiveerd zal de APEX pagina debug informatie weergeven. Hieronder een voorbeeld van debug informatie die wordt weergegeven in de header van de pagina:
0.00: S H O W: application="19169" page="14" workspace="" request="" session="472283790939576"
0.01: Language derived from: FLOW_PRIMARY_LANGUAGE, current browser language: en-us
0.01: alter session set nls_language="AMERICAN"
0.01: alter session set nls_territory="AMERICA"
0.01: NLS: CSV charset=WE8MSWIN1252
0.01: ...NLS: Set Decimal separator="."
0.01: ...NLS: Set NLS Group separator=","
0.01: ...NLS: Set date format="DD-MON-RR"
0.01: ...Setting session time_zone to -06:00
0.01: NLS: Language=en-us
0.01: Application 19169, Authentication: CUSTOM2, Page Template: 14726742502496608190
0.01: ...Session ID 472283790939576 can be used
0.01: ...Application session: 472283790939576, user=ADMIN
0.01: ...Determine if user "ADMIN" workspace "3310010431464928652" can develop application "19169" in workspace "3310010431464928652"
0.01: ...Check for session expiration:
0.01: Session: Fetch session header information
0.01: ...Metadata: Fetch page attributes for application 19169, page 14
0.01: Fetch session state from database
0.02: Branch point: BEFORE_HEADER
0.02: Authorization Check: "14756134089792021103" User: "ADMIN" Component: "PAGE"
0.02: Fetch application meta data
0.02: Computation point: BEFORE_HEADER
0.02: ...Perform computation of item: P14_TIMESTAMP, type=PLSQL_EXPRESSION
0.03: ...Session State: Saved Item "P14_TIMESTAMP" New Value="03-03-2009 03:01:23"
0.03: Processing point: BEFORE_HEADER
0.03: ...Process "Populate Items": PLSQL (BEFORE_HEADER) for c1 in (select TITLE, DESCRIPTION, EXPIRE_DATE from doclib_ANNOUNCEMENTS where an_id = :P14_AN_ID ) loop :P14_TITLE := c1.title; :P14_DESCRIPTION := c1.description; if c1.expire_date != to_date('22-04-2004','DD-MM-YYYY')
0.04: Show page template header
0.05: Computation point: AFTER_HEADER
0.05: Processing point: AFTER_HEADER
0.05: Authorization Check: "14825297114007140887" User: "ADMIN" Component: "tab"
De informatie die hier getoond wordt, bestaat onder andere uit de NLS settings, maar ook specifiekere zaken als berekeningen die worden uitgevoerd en de waardes die velden krijgen in de huidige sessie. Verder is hier te zien welke processen worden uitgevoerd. Al deze informatie kan helpen bij het identificeren van eventuele problemen of om onverwacht gedrag te verklaren. De getallen aan het begin van elke regel geven de verstreken tijd in seconden weer, dit kan helpen om performance problemen te achterhalen. SQL trace informatie kan voor een pagina worden gegenereerd om te weten hoe de SQL en PL/SQL code op de database wordt uitgevoerd. Het aanmaken van trace informatie kan eenvoudig door de parameter p_trace toe te voegen aan de URL:
f?p=100:1&p_trace=YES
Door de pagina met deze parameter aan te roepen, zal een trace file worden gegenereerd in de user dump directory van de database. Zie de Oracle documentatie voor meer informatie over SQL trace.
Naast de informatie in de header, wordt ook bij de elementen van de pagina debug informatie weergegeven. Bij het opbouwen van deze region wordt onder andere weergegeven onder welke user de query wordt uitgevoerd, welke bind variabelen gebruikt worden in de query en het maximaal aantal rijen dat wordt opgehaald. Hieronder een voorbeeld van een pagina uit de Document Library packaged application.
Figuur 2, Debug informatie in een region
Naast de standaard debug meldingen van APEX is het ook mogelijk eigen debug meldingen te maken. Dit kan eenvoudig door de procedure wwv_flow.debug in PL/SQL code te gebruiken. In debug modus zal deze procedure de meegegeven parameter op het scherm weergeven.
Remote debugging
Oracle SQL Developer biedt de mogelijkheid om naast lokaal PL/SQL code te debuggen, ook remote te debuggen. Remote debuggen maakt het mogelijk om PL/SQL code buiten SQL Developer te debuggen, bijvoorbeeld in een SQL*Plus sessie of een APEX sessie. Hiervoor zijn een aantal stappen nodig. De eerste stap is het starten van een remote debug sessie in SQL Developer. Vervolgens moet de aanroepende PL/SQL code een connectie maken met deze debug sessie. De APEX user moet voldoende rechten hebben en de PL/SQL code moet zijn gecompileerd met de debug optie.
Als voorbeeld een stappenplan om een PL/SQL procedure te debuggen vanuit een APEX applicatie, dit voorbeeld komt wederom uit de Document Library packaged application.
- Start de remote debug sessie in SQL Developer door rechts te klikken op de database connectie en de optie "Remote Debug" te kiezen.
Figuur 3, Remote debug dialoog venster
Bovenstaand dialoog venster wordt getoond. De poort kan vrij gekozen worden, maar let op dat deze poort niet wordt geblokkeerd door een firewall. De timeout geeft aan hoeveel seconden SQL Developer deze debug sessie open laat staan, nul betekent dat de sessie niet automatisch wordt gesloten. Het veld Local address kan worden leeg gelaten, dit betekent dat de sessie op de lokale pc draait. Na bevestigen zal de debug sessie worden gestart. - De APEX database users moeten voldoende rechten hebben om een debug sessie vanuit APEX te kunnen starten:
grant debug any procedure to APEX_PUBLIC_USER;
APEX_PUBLIC_USER is het schema dat APEX gebruikt om in te loggen op de database. Let op: gebruikt de database de Embedded PL/SQL Gateway dan moet dit de user ANONYMOUS zijn i.p.v. APEX_PUBLIC_USER.
grant debug connect session to ;
De is het parsing schema van APEX, onder deze user zijn de database objecten aangemaakt.
- De betreffende package moet worden gecompileerd met de debug optie, in dit voorbeeld de package DOCLIB van de Document Library. Verder moet er een breekpunt worden gezet in de DOCLIB package, zodat de uitvoering van de code gepauzeerd wordt.
- De volgende stap is zorgen dat de applicatie connectie maakt met de debug sessie die we in de eerste stap hebben gestart. In dit voorbeeld gaan we de procedure DOCLIB.UPDATE_TASK debuggen. Deze procedure wordt aangeroepen op pagina 75 van de Document Library applicatie in het proces Update task. Dit proces dient aangepast te worden om een connectie met de debug sessie te maken en weer te sluiten.
Figuur 4, Remote debug starten in het proces
De procedure DBMS_DEBUG_JDWP.CONNECT_TCP ('127.0.0.1', 4000) maakt de connectie met de debug sessie. Deze procedure heeft twee parameters: host en poort. De host is in dit geval 127.0.0.1 omdat APEX op de lokale machine draait. Als echter APEX op een webserver draait moet deze host het IP adres zijn van de lokale pc in het netwerk. De poort moet overeenkomen met de opgegeven poort bij het starten van de debug sessie in SQL Developer. De procedure DBMS_DEBUG_JDWP.DISCONNECT verbreekt de verbinding met de debugger, dit is nodig omdat anders dit proces niet zal sluiten. - Start de Document Library APEX applicatie en maak een aanpassing op de Update Task pagina. Na het opslaan van deze aanpassing, zal de uitvoering van de pagina stoppen en de debug sessie in SQL Developer pauzeren op het eerder gemaakte breekpunt. Vanaf dit punt is het mogelijk om door de procedure te stappen en waar nodig de waardes van de variabelen te inspecteren.
Figuur 5, Debuggen in SQL Developer
APEX_PUBLIC_USER is het schema dat APEX gebruikt om in te loggen op de database. Let op: gebruikt de database de Embedded PL/SQL Gateway dan moet dit de user ANONYMOUS zijn i.p.v. APEX_PUBLIC_USER.
Remote debuggen van een APEX applicatie vereist de nodige voorbereiding, maar biedt de mogelijkheid om packages aangeroepen vanuit APEX te debuggen. Remote debugging is overigens pas mogelijk bij Oracle databases vanaf versie 9i release 2.
Javascript
We hebben gezien dat debuggen binnen APEX en Oracle packages mogelijk is, maar hoe zit het met fouten opsporen in Javascript? Zodra in de Javascript code iets fout gaat, is de foutmelding niet zichtbaar in APEX. Een oplossing hiervoor is een Firefox add-on genaamd Firebug, Firebug maakt melding van Javascript fouten en toont hierover alle relevante informatie.
Figuur 6, Firebug melding van een Javascript fout
Wat erg handig is aan Firebug is de mogelijkheid om Javascript code te debuggen. Het is zeer eenvoudig breekpunten te zetten en de uitvoering van Javascript code te volgen.
Figuur 7, Debuggen met Firebug
Firebug heeft nog meer functionaliteit om het ontwikkelen voor web applicaties makkelijker te maken, alle mogelijkheden en uitleg over het werken met Firebug is te vinden op de Firebug site.
Conclusie
Bugs vinden en oplossen kan een tijdrovende bezigheid zijn, maar gelukkig heeft de Oracle APEX ontwikkelaar hiervoor diverse mogelijkheden. Standaard biedt APEX een debug optie waar veel informatie wordt getoond over de processen die de APEX pagina opbouwen. Verder is er de SQL trace mogelijkheid om de uitvoering van SQL en PL/SQL code op de database inzichtelijk te maken. Remote debugging maakt het mogelijk om Oracle packages te debuggen tijdens het verwerken van de APEX pagina. Javascript fouten opsporen kan niet in APEX, maar gelukkig is er een oplossing als Firebug, waardoor het debuggen van alle elementen van een APEX applicatie toch mogelijk is.
Er is niet 1 oplossing om alle technieken binnen een APEX applicatie te debuggen, maar de besproken debug mogelijkheden zijn redelijk eenvoudig en snel te gebruiken en geven de ontwikkelaar genoeg mogelijkheden om de gevreesde bugs op te sporen.
Referenties
- Oracle Application Express:
http://www.oracle.com/technology/products/database/application_express/index.html - Application Express forum op OTN:
http://forums.oracle.com/forums/forum.jspa?forumID=137 - SQL Developer
http://www.oracle.com/technology/products/database/sql_developer/index.html
Over de auteur
Peter van der Neut is Oracle consultant bij Whitehorses en heeft 9 jaar ervaring in de IT. Hij houdt zich voornamelijk bezig met applicatieontwikkeling met Oracle technologie en heeft veel ervaring met PL/SQL, Forms, Designer en Application Express. Daarnaast houdt hij zich bezig met nieuwe ontwikkelingen als Oracle ADF/JHeadstart.

Reacties
Nieuwe reactie inzenden