Tomcat Debug JPDA

De EjnTricks

Il n'est pas rare de devoir debugger une application déployer sur une machine distante, en cas de bug par exemple. Comme mentionné dans l'article Eclipse, il est possible de mettre en place un serveur local et d'effectuer le pas à pas. Mais si l'analyse doit être réalisée "sur" la machine distante, il est possible d'utiliser le protocle JPDA afin d'exécuter le code localement pour une exécution distante.

Cet article détail la mise en place de la configuration sous Eclipse et dans les scripts de démarrage de Tomcat, avec pour exemple l'étude de CXF.


Hand-icon.png Votre avis

Nobody voted on this yet

 You need to enable JavaScript to vote


Study icon.png Analyse

Le mode à distance repose donc sur l'utilisation du protocole JPDA. L'analyse des scripts de démarrage de Tomcat est nécessaire pour connaitre comment le mettre en place.

Dans le cadre d'une installation sous Windows, Tomcat se démarre généralement à l'aide du script bin/startup.bat, exemple pour la version 6.0.18

@echo off
rem Licensed to the Apache Software Foundation (ASF) under one or more
rem contributor license agreements.  See the NOTICE file distributed with
rem this work for additional information regarding copyright ownership.
rem The ASF licenses this file to You under the Apache License, Version 2.0
rem (the "License"); you may not use this file except in compliance with
rem the License.  You may obtain a copy of the License at
rem
rem     http://www.apache.org/licenses/LICENSE-2.0
rem
rem Unless required by applicable law or agreed to in writing, software
rem distributed under the License is distributed on an "AS IS" BASIS,
rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rem See the License for the specific language governing permissions and
rem limitations under the License.

if "%OS%" == "Windows_NT" setlocal
rem ---------------------------------------------------------------------------
rem Start script for the CATALINA Server
rem
rem $Id: startup.bat 562770 2007-08-04 22:13:58Z markt $
rem ---------------------------------------------------------------------------

rem Guess CATALINA_HOME if not defined
set CURRENT_DIR=%cd%
if not "%CATALINA_HOME%" == "" goto gotHome
set CATALINA_HOME=%CURRENT_DIR%
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
cd ..
set CATALINA_HOME=%cd%
cd %CURRENT_DIR%
:gotHome
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome

set EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat

rem Check that target executable exists
if exist "%EXECUTABLE%" goto okExec
echo Cannot find %EXECUTABLE%
echo This file is needed to run this program
goto end
:okExec

rem Get remaining unshifted command line arguments and save them in the
set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgs

call "%EXECUTABLE%" start %CMD_LINE_ARGS%

:end

En fin de script, le script catalina.bat est exécutée avec comme premier argument start suivi des arguments passés en ligne de commande.

Le script catalina.bat est trop volumineux pour être repris dans le cadre de cet article. Cependant des parties doivent être étudiées pour comprendre l'activation du mode JPDA.

set JPDA=

if not ""%1"" == ""jpda"" goto noJpda
set JPDA=jpda
if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport
set JPDA_TRANSPORT=dt_shmem
:gotJpdaTransport
if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress
set JPDA_ADDRESS=jdbconn
:gotJpdaAddress
if not "%JPDA_SUSPEND%" == "" goto gotJpdaSuspend
set JPDA_SUSPEND=n
:gotJpdaSuspend
if not "%JPDA_OPTS%" == "" goto gotJpdaOpts
set JPDA_OPTS=-agentlib:jdwp=transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND%
:gotJpdaOpts
shift
:noJpda

Dans cette partie, si le premier argument de la ligne de commande est jpda, la variable locale JPDA est renseignée avec la valeur jpda. Puis les variables JPDA_TRANSPORT, JPDA_ADDRESS, JPDA_SUSPEND et JPDA_OPTS sont initialisées avec des valeurs par défaut si elles ne sont pas préalablement configurées.

Lors du lancement du serveur Tomcat, la variable locale JPDA est contrôlée. Si celle-ci est renseignée, des paramètres complémentaires sont ajoutés depuis la variable JPDA_OPTS.

if not "%JPDA%" == "" goto doJpda
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end
:doSecurity
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager 
-Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%"
-Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end
:doJpda
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurityJpda
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" 
-Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end
:doSecurityJpda
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager 
-Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%"
-Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end

:end


Run-icon.png Activation

L'analyse du précédent paragraphe met en évidence que le script catalina.bat doit être lancé avec jpda comme premier argument. Or, le script startup.bat force la valeur start à cette position. Il est donc "impossible" d'activer le mode JPDA depuis le script startup.bat, sauf en le modifiant.

Il faut utiliser directement catalina.bat avec la commande suivante.

catalina.bat jpda start

Dans la console d'exécution, la trace suivante doit apparaître.

Listening for transport dt_socket at address: 8000


Configuration-icon.png Configuration Eclipse

Une fois le serveur Tomcat en mode JPDA, il est possible de l'écouter depuis Eclipse. En laissant tous les paramètres par défaut, l'activation est très simple.

Dans un premier temps, il faut sélectionner le projet, cxfTutorial dans le cadre de cet article, puis aller dans la configuration des runs à partir du menu Run → Run configurations.... Une fenêtre de configuration apparaît.


Il faut ensuite sélectionner la section Remote Java Application et créer une nouvelle configuration en cliquant sur le premier bouton de la barre d'outils.


Une configuration est créée avec toutes les valeurs par défaut concernant le serveur et le port à écouter. En ayant sélectionner le projet avec les sources de l'application, celui-ci est utilisé pour nommer la configuration et pour l'attachement des sources.


L'onglet Source de la configuration permet de spécifier l'emplacement des sources pour le code exécuté.


Cela permet d'ajouter d'autre projet dans la configuration, utile dans le cadre d'une implémentation multi module. Le projet sélectionné est automatique associé à la configuration avec le libellé Default.

Eclipse est alors opérationnel pour exécuter le pas à pas de l'application, comme si le code était exécuté localement. Il est alors possible de positionner des points d'arrêt, d'inspecter les variables ... comme si le code était exécuté au sein d'Eclipse.