Categories
Java

Remote Debugging

I need to directly debug on the application Tomcat server, not only on my local Tomcat instance.

Compile Java code

For debugging we need to keep the line numbers while compiling.
To build the war file we use an ANT script and we have to add the debug and debuglevel attributes in the javac tag:

<javac srcdir="${src}" destdir="${build}" 
       includeantruntime="false" 
       encoding="UTF-8" source="1.8" 
       fork="true" 
       debug="on" debuglevel="lines,vars,source" 
       verbose="true">
  [...]
</javac>

Configure Tomcat server

To enable remote debugging on the Tomcat server add some arguments to CATALINA_OPTS in setenv.sh file:

ATALINA_HOME=/app/myApp/tomcat
CATALINA_BASE=/app/myApp/tomcat
CATALINA_PID=/app/myApp/tomcat/tomcat.pid
JAVA_HOME=/app/java/jdk8u265-b01-jre
CATALINA_OPTS="$CATALINA_OPTS -Djava.library.path=/app/library -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/library
export LD_LIBRARY_PATH
JAVA_OPTS="${JAVA_OPTS} -Djavax.net.ssl.trustStore=/app/certs/corporate_truststore.jks -Djavax.net.ssl.trustStorePassword=secret -Xms256M -Xmx1024M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/app/myApp/dump"

Configure Eclipse

Create a new debug configuration:


Categories
Java

Deploy to Tomcat

Deploy myApp.war file to Tomcat application server, using Tomcat manager app and an ant script.

Make a folder "ant" in your project and this it the folder for all other actions below.

Make a folder "dist" and generate your myApp.war file into this folder with the "build.xml" script.

Make a folder "tomcat-libs" and copy following files from your tomcat installation:

  • catalina-ant.jar
  • catalina.jar
  • servlet-api.jar
  • jsp-api.jar

Create file "tomcat.properties" with properties for tomcat server and tomcat manager app.

Create "deploy.xml" file for deployment.

Execute deploy.xml script with ant, it must show the info sections with properties of your tomcat.properties file.

Execute deploy-webapp target from deploy.xml script to deploy your myApp.war file to tomcat server through the tomcat manager app.

If you are using for example Jenkins, you can set the "secprops.location" from outside the script, so you can use the same script for different tomcat installations.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE project>
<project name="myApp" default="info" basedir=".">

  <description>
    myApp ant deploy file.
  </description>

  <property name="secprops.location" value="tomcat.properties" />
  <property file="${secprops.location}" />

  <property name="war.file" value="dist/myApp.war" />

  <target name="info">
    <echo message="-------------------------------------------------------------------" />
    <echo message="Commands:" />
    <echo message="  start-webapp" />
    <echo message="  stop-webapp" />
    <echo message="  undeploy-webapp" />
    <echo message="  deploy-webapp" />
    <echo message="  sessions-webapp" />
    <echo message="-------------------------------------------------------------------" />
    <echo message="Properties: "/>
    <echo message="tomcat.manager.url = ${tomcat.manager.url}"/>
    <echo message="tomcat.username    = ${tomcat.username}"/>
    <echo message="tomcat.password    = ${tomcat.password}"/>
    <echo message="webapp.name        = ${webapp.name}"/>
    <echo message="war.file           = ${war.file}"/>
    <echo message="-------------------------------------------------------------------" />
  </target>

  <path id="catalina-ant-classpath">
    <fileset dir="tomcat-libs">
      <include name="catalina-ant.jar" />
      <include name="catalina.jar" />
    </fileset>
  </path>

  <taskdef name="catalina-start" classname="org.apache.catalina.ant.StartTask" classpathref="catalina-ant-classpath" />
  <taskdef name="catalina-stop" classname="org.apache.catalina.ant.StopTask" classpathref="catalina-ant-classpath" />
  <taskdef name="catalina-deploy" classname="org.apache.catalina.ant.DeployTask" classpathref="catalina-ant-classpath" />
  <taskdef name="catalina-undeploy" classname="org.apache.catalina.ant.UndeployTask" classpathref="catalina-ant-classpath" />
  <taskdef name="catalina-sessions" classname="org.apache.catalina.ant.SessionsTask" classpathref="catalina-ant-classpath" />
  
  <target name="sessions-webapp">
    <catalina-sessions url="${tomcat.manager.url}" username="${tomcat.username}" password="${tomcat.password}" path="/${webapp.name}" failonerror="false" />
  </target>
  
  
  <target name="stop-webapp">
    <catalina-stop url="${tomcat.manager.url}" username="${tomcat.username}" password="${tomcat.password}" path="/${webapp.name}" failonerror="false" />
  </target>

  <target name="start-webapp">
    <catalina-start url="${tomcat.manager.url}" username="${tomcat.username}" password="${tomcat.password}" path="/${webapp.name}" />
  </target>

  <target name="undeploy-webapp">
    <catalina-undeploy url="${tomcat.manager.url}" username="${tomcat.username}" password="${tomcat.password}" path="/${webapp.name}" failonerror="false" />
  </target>

  <target name="deploy-webapp">
    <echo message="START to deploy file ${war.file} to Tomcat Server: ${tomcat.manager.url}" />
    <catalina-deploy url="${tomcat.manager.url}" username="${tomcat.username}" password="${tomcat.password}" path="/${webapp.name}" war="file:${war.file}" update="true"/>
    <echo message="END of deployment" />
  </target>

</project>
tomcat.manager.url=http://myAppServer:7011/manager/text
tomcat.username=tomcat
tomcat.password=tomcat
webapp.name=myApp
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE project>
<project name="myApp" default="clean" basedir=".">
  <description>
    myApp ant build file.
  </description>
  <!-- Set global properties for this build -->
  <property name="src" location="../source"/>
  <property name="webcontent" location="../WebContent"/>
  <property name="build" location="build"/>

  <tstamp prefix="build-info">
    <format property="current-date" pattern="d-MMMM-yyyy" locale="en" />
    <format property="current-time" pattern="hh:mm:ss a z" locale="en" />
  </tstamp>

  <target name="init">
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}/lib"/>
  </target>

  <target name="compile" depends="init" description="compile the source">
    <!-- Compile the Java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}" includeantruntime="false" encoding="UTF-8">
      <classpath>
        <!-- Taken from Apache Tomcat 8.5 lib folder -->
        <pathelement path="tomcat-libs/servlet-api.jar"/>
        <pathelement path="tomcat-libs/jsp-api.jar"/>
      </classpath>
    </javac>
    <!-- Copy all non-java ressoures from source folder -->
    <copy todir="${build}">
      <fileset dir="${src}" excludes="**/*.java" />
    </copy>

  </target>

  <target name="war" depends="compile">
    <war destfile="dist/myApp.war" webxml="${webcontent}/WEB-INF/web.xml">
      <fileset dir="${webcontent}"/>
      <classes dir="${build}"/>
      <manifest>
        <attribute name="Manifest-Version" value="1.0"/>
        <attribute name="Built-On" value="${build-info.current-date}"/>
        <attribute name="Built-At" value="${build-info.current-time}"/>
      </manifest>
    </war>
  </target>

  <target name="clean" description="clean up">
    <!-- Delete the ${build} directory trees -->
    <delete dir="${build}"/>
  </target>
</project>